GeoDjango GeoQuerySet.distance() results in 'ST_Distance output only available on GeometryFields' when specifying a reverse relationship in field_name

让人想犯罪 __ 提交于 2019-12-11 03:14:56

问题


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.


回答1:


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).



来源:https://stackoverflow.com/questions/25047964/geodjango-geoqueryset-distance-results-in-st-distance-output-only-available-o

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!