GeoDjango:如何执行空间关闭记录的查询

问题描述 投票:0回答:1

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

有没有人知道更好的方式(更有效)执行这样的查询,或者可能是我的代码失败的原因?

我非常感谢。

python django postgis django-orm geodjango
1个回答
1
投票

我终于设法解决了它,但最后我不得不执行原始的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()]

参考文献:

© www.soinside.com 2019 - 2024. All rights reserved.