相关模型上的 GeoDjango Distance() 注解
GeoDjango Distance() Annotation on Related Model
我有一个 Profile
class,它是一个带有 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
您可以使用 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
对象的距离,然后将该距离注释到适当的配置文件。
我有一个 Profile
class,它是一个带有 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
您可以使用 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
对象的距离,然后将该距离注释到适当的配置文件。