GeoDjango按距离模型字段过滤

时间:2015-09-16 13:16:49

标签: python django geodjango

我的问题与this几乎相同。但它已经很老了,感觉它必须是一个相当普遍的场景,可能有更好的解决方案。

我的模型类似于:

class Person(models.Model):
    location = models.PointField(srid=4326)
    willing_to_travel = models.IntegerField()

如果我想要一个点p的设定距离(例如10英里)内的所有人物实例,我可以这样做:

Person.objects.filter(location__distance_lte=(p, D(mi=10)))

但我希望获得距离特定位置willing_to_travel距离内的所有人物实例。

1 个答案:

答案 0 :(得分:1)

可以感谢Django 1.9中引入的upper bound

  

允许用户访问要使用的地理数据库功能   Django中的注释,聚合或过滤器。

我们最感兴趣的是Distance,它可以在您的情况下应用如下:

from django.contrib.gis.db.models.functions import Distance
from django.db.models import F
Person.objects.annotate(distance=Distance('location', p)
       ).filter(distance__lte=F('willing_to_travel'))

请注意,此处存在细微差别,而不是直接在此处使用Geographic Database Functions,我们创建了一个注释,可以生成距离列。然后我们使用模型查询集上的标准__lt比较。这(大致)转换为

   ... WHERE ST_Distance(app_person.location, ST_GeogFromWKB(...)) < 
       app_person.willing_to_travel

哪个类似于distance_lte生成的那个它不如使用ST_Dwithin但它完成工作的那个效率

您需要将位置转换为地理位置,因为此查询会在字段的“单位”上运行。这意味着学位。如果您使用地理字段,则距离将以米为单位。