python - GeoDjango:如何执行空间接近记录的查询
问题描述
我有两个 Django 模型(A 和 B),它们没有任何外键相关,但都有一个几何字段。
class A(Model):
position = PointField(geography=True)
class B(Model):
position = PointField(geography=True)
我想在空间上关联它们,即给定 A 的查询集,能够获得 B 的查询集,其中包含与 A 的距离小于给定距离的那些记录。
我还没有找到使用纯 Django 的 ORM 来做这样的事情的方法。
当然,我可以在 A 中编写一个属性,例如:
@property
def nearby(self):
return B.objects.filter(position__dwithin=(self.position, 0.1))
但这仅允许我在每个实例上获取附近的记录,而不是在单个查询中,这远非高效。
我也尝试过这样做:
nearby = B.objects.filter(position__dwithin=(OuterRef('position'), 0.1))
query = A.objects.annotate(nearby=Subquery(nearby.values('pk')))
list(query) # error here
但是,我在最后一行收到此错误:
ValueError: This queryset contains a reference to an outer query and may only be used in a subquery
有人知道执行此类查询的更好方法(更有效),或者我的代码失败的原因吗?
我非常感谢。
解决方案
我终于设法解决了它,但最后我不得不执行一个原始的 SQL 查询。
这将返回所有带有注释的 A 记录,包括所有附近 B 记录的列表:
from collections import namedtuple
from django.db import connection
with connection.cursor() as cursor:
cursor.execute('''SELECT id, array_agg(b.id) as nearby FROM myapp_a a
LEFT JOIN myapp_b b ON ST_DWithin(a.position, p.position, 0.1)
GROUP BY a.id''')
nt_result = namedtuple('Result', [col[0] for col in cursor.description])
results = [nt_result(*row) for row in cursor.fetchall()]
参考:
推荐阅读
- sql - 在唯一列上选择(DISTINCT?)
- reactjs - 将“返回”按钮标签相应地更改为使用 react-router-dom 访问的最后一页
- r - 如何快速创建一个变量,该变量全部组合了数据框中特定列的字符串值?
- php - 获取 woocommerce_form_field 选择的选定值
- r - R Shiny - 如何用 iframe 填充浏览器窗口的整个空间
- vaticle-typedb - 有没有办法只获取最深层的节点?
- javascript - 子组件中未定义 VUE 索引道具
- android - Android上的状态栏重叠应用程序
- python -
(cx_Oracle.DatabaseError) ORA-01843: 不是一个有效的月份 - jquery - 动态追加 Json 数据无法正常工作