gpt4 book ai didi

python - 基于相关 M2M 字段对查询集进行排序

转载 作者:行者123 更新时间:2023-12-01 07:55:09 24 4
gpt4 key购买 nike

我目前正在尝试返回基于三个模型的查询集。

位置模型

class Location(models.Model):
...
lat = models.FloatField()
lng = models.FloatField()

用户模型(从 Django User 扩展)

class UserProfile(models.Model):
...
user = OneToOneField(User)
locations = ManyToManyField(Location)

案例模型

class Case(models.Model):
...
owner = models.ForeignKey(User)
completed = models.BooleanField()

我使用geopy返回接近输入纬度/经度的位置

def get_locations_nearby_coords(latitude, longitude, max_distance=None):
"""
Return objects sorted by distance to specified coordinates
which distance is less than max_distance given in kilometers
"""
# Great circle distance formula
gcd_formula = "6371 * acos(cos(radians(%s)) * cos(radians(lat)) * cos(radians(long) - radians(%s)) + sin(radians(%s)) * sin(radians(lat)))"
distance_raw_sql = RawSQL(
gcd_formula,
(latitude, longitude, latitude)
)
qs = Location.objects.all().annotate(
distance=distance_raw_sql).order_by('distance')
if max_distance is not None:
qs = qs.filter(distance__lt=max_distance)
return qs

我想要返回的是按每个UserProfile 的已完成案例数量排序的 10 个最接近的位置

一个用户可以拥有多个位置,并且一个位置可以与多个用户关联,因此我选择了 m2m 字段。

我不能有任何重复项,但是,如果某个位置有多个用户,则该位置可以在列表中显示两次,但最终列表应按 10 进行切片。

编辑:

试图澄清应该返回什么。

假设我有 3 个靠近我的位置(这是已知数据)

1. Location 1 (Closest)
2. Location 2
3. Location 3 (Furthest)

位置 1 有 1 位用户,已完成 3 个案例。 位置 2 有 2 位用户,用户 1 已完成 10 个案例,用户 2 已完成 2 个案例。位置 3 有 1 位用户,已完成 4 个案例。应该返回的内容如下

1. Location 2 - User 1 - 10 Cases
2. Location 3 - User 1 - 4 Cases
3. Location 1 - User 1 - 3 Cases
4. Location 2 - User 2 - 2 Cases

最佳答案

首先,我建议应用显式关系名称以在查询中使用它们。

要将已完成的案例计数附加到您的查询集中,您可以使用以下命令:

qs = qs.annotate(completed_cases=Count('user__case', filter=Q(user__case__completed=True))

最终的切片就像[:10]

一样简单
qs = qs.order_by('distance', '-completed_cases`, 'id', )[:10]

id - 避免相同距离和案例数的随机性。

更新

# finding locations
...
qs = qs.order_by('distance', 'id', )[:10]

# finding users with completed cases
final_qs = User.objects.filter(locations__in=qs, ).\
annotate(
completed_cases=Count('case', filter=Q(case__completed=True),
location_id=F('locations__id'),
).order_by('-completed_cases', 'id')[:10]

关于python - 基于相关 M2M 字段对查询集进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56019615/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com