我的问题与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
距离内的所有人物实例。
答案 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但它完成工作的那个效率
您需要将位置转换为地理位置,因为此查询会在字段的“单位”上运行。这意味着学位。如果您使用地理字段,则距离将以米为单位。