GeoDjango GeoQuerySet.distance() 在指定反向关系字段时出现 'ST_Distance output only available on GeometryFields
根据文档和其他问题,按距离对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))
到这里为止,一切正常。问题出现在我想按距离对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 output only available on 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)也没有帮助。
1 个回答
我怀疑你遇到的问题跟Django的支持票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
作为查询集的好处(查询集可以进一步过滤、切片等等)。