当在field_name中指定反向关系时,GeoDjango GeoQuerySet.distance()导致“ST_Distance输出仅在GeometryFields上可用” [英] GeoDjango GeoQuerySet.distance() results in 'ST_Distance output only available on GeometryFields' when specifying a reverse relationship in field_name
问题描述
说我在两个不同的应用程序中有两个模型。 appA中的一个模型,另一个在appB中的模型如下:
#appA / models.py
class Store .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 = Store.objects.filter(storelocation__location__dwithin(user_location,D(mi = 2))
到目前为止这么好,一切都到这里工作,问题开始于我想要现在按 user_location
的距离排序:
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
模型的位置
字段是 PointField
这是一个 GeometryField
。所以问题是通过 field_name ='storelocation__location'
完成的反向关系查找。
有一个Django支持机票( https://code.djangoproject.com/ticket/22352 )请求支持反向OneToOne关系的 field_name
中的关系查找,但是我的模型通过ForeignKey具有OneToMany关系,因此我不知道支持票证是否适用于此问题。
从Django文档( https://docs.djangoproject.com/en/1.6/ref/contrib/gis/geoquerysets/#geoqueryset-methods )似乎我在这里滥用任何东西。
是否允许使用GeoQuerySet方法的 field_name
参数进行反向关系查找?或者我只是做错了?
此问题提供的解决方案(一个ForeignKey关系的GeoDjango距离查询)也没有帮助。
我怀疑你在 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')]
但是,这失去了好处存储
是一个查询(可以进一步过滤,切片等)。
From the docs and other questions, sorting a GeoQuerySet by distance should be straightforward, but I'm having trouble getting it work. Here is an example to demonstrate the situation of the problem:
Lets say I got two models in two different apps. One model in appA and another in appB as defined below:
# 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()
Now, I want to get all the Stores
that are within two miles of a user's location (user_location
) like so:
stores = Store.objects.filter(storelocation__location__dwithin(user_location, D(mi=2))
So far so good. Everything up to here works. The problem starts when I want to now sort the Stores
by their distance to user_location
:
stores = Store.objects.filter(storelocation__location__dwithin(user_location, D(mi=2))\
.distance(user_loc, field_name='storelocation__location')\
.order_by('distance')
This results into TypeError: ST_Distance output only available on GeometryFields
.
The location
field of the StoreLocation
model is a PointField
which is a GeometryField
. So the issue is with the reverse relationship lookup done by field_name='storelocation__location'
.
There is a Django support ticket (https://code.djangoproject.com/ticket/22352) requesting support for reverse relationship lookups in field_name
for OneToOne relationships, but my models have a OneToMany relationship through a ForeignKey so I'm not sure if the support ticket applies to this problem.
Judging from the Django documentation (https://docs.djangoproject.com/en/1.6/ref/contrib/gis/geoquerysets/#geoqueryset-methods) it doesn't seem like I'm misusing anything here.
Are reverse relationship lookups allowed with the field_name
argument of GeoQuerySet methods? Or am I just doing something wrong?
The solution provided in this question (GeoDjango distance query for a ForeignKey Relationship) didn't help either.
I suspect you are getting bit by the same issue mentioned in Django support ticket 22352, since related fields (whether one-to-one or one-to-many) share much of the same code.
You can still efficiently get nearby stores ordered by distance:
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')]
However, this loses the benefits of having stores
be a queryset (which could be further filtered, sliced, etc).
这篇关于当在field_name中指定反向关系时,GeoDjango GeoQuerySet.distance()导致“ST_Distance输出仅在GeometryFields上可用”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!