Skip to main content
 首页 » 编程设计

python之在 field_name 中指定反向关系时,GeoDjango GeoQuerySet.distance() 结果为 'ST_Distance output only available on GeometryFields'

2025年05月04日24cyq1162

根据文档和其他问题,按距离对 GeoQuerySet 进行排序应该很简单,但我无法让它正常工作。下面举例说明问题的情况:

假设我在两个不同的应用程序中有两个模型。 appA 中的一个模型和 appB 中的另一个模型定义如下:

# appA/models.py 
class Store(models.Model): 
        title = models.CharField() 
 
 
# appB/models.py 
from appA.models import Store 
 
class StoreLocation(models.Model): 
    store = models.ForiegnKey(Store) 
    location = models.PointField() 

现在,我想获取用户位置 (user_location) 两英里范围内的所有 Stores,如下所示:

stores = Store.objects.filter(storelocation__location__dwithin(user_location, D(mi=2)) 

到目前为止一切顺利。到这里为止的一切都有效。当我现在想根据到 user_location 的距离对 Stores 进行排序时,问题就开始了:

stores = Store.objects.filter(storelocation__location__dwithin(user_location, D(mi=2))\ 
         .distance(user_loc, field_name='storelocation__location')\ 
         .order_by('distance') 

这会导致 TypeError:ST_Distance 输出仅在 GeometryFields 上可用。

StoreLocation 模型的location 字段是一个PointField,它是一个GeometryField。所以问题在于 field_name='storelocation__location' 完成的反向关系查找。

有一张 Django 支持票证 (https://code.djangoproject.com/ticket/22352) 请求支持在 field_name 中为 OneToOne 关系进行反向关系查找,但我的模型通过 ForeignKey 具有 OneToMany 关系,所以我不确定是否支持票适用于此问题。

从 Django 文档 (https://docs.djangoproject.com/en/1.6/ref/contrib/gis/geoquerysets/#geoqueryset-methods) 来看,我似乎没有滥用任何东西。

GeoQuerySet 方法的 field_name 参数是否允许反向关系查找?还是我只是做错了什么?

这个问题 ( GeoDjango distance query for a ForeignKey Relationship ) 中提供的解决方案也没有帮助。

请您参考如下方法:

我怀疑您遇到了 Django support ticket 22352 中提到的相同问题,因为相关字段(无论是一对一还是一对多)共享大部分相同的代码。

您仍然可以高效地按距离订购附近的商店:

locations = StoreLocation.objects.filter(location__dwithin=(user_location, D(mi=2))) 
locations = locations.distance(user_location).order_by('distance') 
stores = [sl.store for sl in locations.select_related('store')] 

但是,这失去了将 stores 作为查询集(可以进一步过滤、切片等)的好处。