相关模型的GeoDjango Distance()批注

时间:2018-07-24 20:19:42

标签: python django geodjango

我有一个Profile类,它是一个具有Location模型的OneToOne。每个配置文件都有一个唯一的位置。

class Location(models.Model):
    profile = models.OneToOne(Profile)
    point = PointField()

在我的一个视图中,我显示了一个配置文件列表。例如,我首先找到具有位置的配置文件,然后找到关联的配置文件。

ref_location = Point(0,0) # point to calculate distances from
locations = Location.objects.filter(point__distance_lte=(ref_location, D(m=50 * 1000))) \
profiles = Profile.objects.filter(pk__in=locations.values('profile_id'))

我想要的是能够知道到每个配置文件实例的距离,例如我想做类似的事情:

profiles = Profile.objects.filter(pk__in=locations.values('profile_id'))\
.annotate(distance=Distance('location__point', ref_location))

然后遍历

for p in profiles:
    print(p.distance.km)

不可能

我可以做的是annotate locations,这没什么用,因为我在模板中循环了profiles,而不是locations

1 个答案:

答案 0 :(得分:3)

您可以使用Subquery(对于Django版本> = 1.11)来组成此查询:

locations = Location.objects.filter(
    point__distance_lte=(OuterRef('ref_location'), D(m=50 * 1000))
).annotate(distance=Distance(OuterRef('point'), ref_location))

profiles = Profile.objects.filter(
    pk__in=Subquery(locations.values('profile_id')
).annotate(distance=Subquery(locations.values('distance')))

或者对于Django版本1.11,您可以按以下方式编写此查询:

locations = Location.objects.filter(
    point__distance_lte=(ref_location), D(m=50 * 1000))
).annotate(distance=Distance('point', ref_location))

profiles = Profile.objects.filter(
    pk__in=locations.values('profile_id')
).annotate(distance=locations.values('distance'))

要点是要注释到Location对象的距离,然后要注释该距离到适当的轮廓。