相关模型的GeoDjango Distance()批注 [英] GeoDjango Distance() Annotation on Related Model

查看:51
本文介绍了相关模型的GeoDjango Distance()批注的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Profile class which is a OneToOne with Location model. Every profile has one and only location.

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

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

In one of my views, I display a list of profiles. For example, I first find profiles with locations and then find associated profiles.

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'))

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

What I would want is to be able to know the distance to each of these profile instances, e.g. I want to do something like:

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 ,不是位置

What I can do is annotate the locations instead, which isn't much use, because in the template I loop over profiles, not locations

推荐答案

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

You can use Subquery (for Django version >= 1.11) to compose this query:

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您可以按以下方式编写此查询:

Or for Django version < 1.11 you can compose this query as follows:

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 对象的距离,然后注释与适当的轮廓的距离.

The point is that you annotate the distance to the Location objects and then you annotate that distance to the appropriate profile.

这篇关于相关模型的GeoDjango Distance()批注的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆