【问题标题】:GeoDjango: How to perform a query of spatially close recordsGeoDjango:如何执行空间接近记录的查询
【发布时间】:2019-04-19 23:32:45
【问题描述】:

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

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

    参考资料:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 2018-08-15
      • 2015-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多