当在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

查看:162
本文介绍了当在field_name中指定反向关系时,GeoDjango GeoQuerySet.distance()导致“ST_Distance输出仅在GeometryFields上可用”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从文档和其他问题,按距离排序GeoQuerySet应该是直截了当的,但我无法使它工作。以下是一个示例来说明问题的情况:



说我在两个不同的应用程序中有两个模型。 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆