【问题标题】:GeoDjango Distance() Annotation on Related ModelGeoDjango Distance() 对相关模型的注解
【发布时间】:2018-07-24 20:19:41
【问题描述】:

我有一个 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

【问题讨论】:

    标签: python django geodjango


    【解决方案1】:

    您可以使用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 版本

    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 对象的距离,然后将该距离注释到适当的配置文件。

    【讨论】:

      猜你喜欢
      • 2015-07-16
      • 1970-01-01
      • 1970-01-01
      • 2020-05-20
      • 1970-01-01
      • 1970-01-01
      • 2011-01-10
      • 2015-12-23
      • 1970-01-01
      相关资源
      最近更新 更多