Фильтрация запроса с использованием отношения географического диапазона django не принимается

Я пытаюсь отфильтровать какой-либо элемент, используя географические отношения span с geodjango, но я не понимаю, почему он не работает. Рассмотрим этот пример:

class Location(models.Model):
 name = models.CharField(max_length=32,)
 marker = models.PointField(srid=4326) # the marker
 objects = models.GeoManager()
class Item(models.Model):
 name = models.CharField(max_length=200)
 location = models.ForeignKey(Location)
poly = Polygon(
[(0.02780914306640625, 52.158980248467095),
 (0.22350311279296875, 52.158980248467095),
 (0.22350311279296875, 52.253657959623055),
 (0.02780914306640625, 52.253657959623055),
 (0.02780914306640625, 52.158980248467095)]
)

Если я запрашиваю ( "Местоположение" - это существующее место в db)

Item.objects.filter(location__name__exact="A location")

он работает.

Если вместо этого я запрошу

Item.objects.filter(location__marker__within=poly)

Я получаю эту ошибку

---------------------------------------------------------------------------
FieldError Traceback (most recent call last)
/home/mattions/.virtualenvs/ssouk_env/local/lib/python2.7/site-packages/django/core/management/commands/shell.pyc in <module>()
----> 1 Item.objects.filter(location__marker__within=poly)
/home/mattions/.virtualenvs/ssouk_env/local/lib/python2.7/site-packages/django/db/models/manager.pyc in filter(self, *args, **kwargs)
 141 
 142 def filter(self, *args, **kwargs):
--> 143 return self.get_query_set().filter(*args, **kwargs)
 144 
 145 def aggregate(self, *args, **kwargs):
/home/mattions/.virtualenvs/ssouk_env/local/lib/python2.7/site-packages/django/db/models/query.pyc in filter(self, *args, **kwargs)
 619 set.
 620 """
--> 621 return self._filter_or_exclude(False, *args, **kwargs)
 622 
 623 def exclude(self, *args, **kwargs):
/home/mattions/.virtualenvs/ssouk_env/local/lib/python2.7/site-packages/django/db/models/query.pyc in _filter_or_exclude(self, negate, *args, **kwargs)
 637 clone.query.add_q(~Q(*args, **kwargs))
 638 else:
--> 639 clone.query.add_q(Q(*args, **kwargs))
 640 return clone
 641 
/home/mattions/.virtualenvs/ssouk_env/local/lib/python2.7/site-packages/django/db/models/sql/query.pyc in add_q(self, q_object, used_aliases, force_having)
 1248 else:
 1249 self.add_filter(child, connector, q_object.negated,
-> 1250 can_reuse=used_aliases, force_having=force_having)
 1251 if force_having:
 1252 self.having.end_subtree()
/home/mattions/.virtualenvs/ssouk_env/local/lib/python2.7/site-packages/django/db/models/sql/query.pyc in add_filter(self, filter_expr, connector, negate, trim, can_reuse, process_extras, force_having)
 1120 parts, opts, alias, True, allow_many, allow_explicit_fk=True,
 1121 can_reuse=can_reuse, negate=negate,
-> 1122 process_extras=process_extras)
 1123 except MultiJoin, e:
 1124 self.split_exclude(filter_expr, LOOKUP_SEP.join(parts[:e.level]),
/home/mattions/.virtualenvs/ssouk_env/local/lib/python2.7/site-packages/django/db/models/sql/query.pyc in setup_joins(self, names, opts, alias, dupe_multis, allow_many, allow_explicit_fk, can_reuse, negate, process_extras)
 1473 if pos != len(names) - 1:
 1474 if pos == len(names) - 2:
-> 1475 raise FieldError("Join on field %r not permitted. Did you misspell %r for the lookup type?" % (name, names[pos + 1]))
 1476 else:
 1477 raise FieldError("Join on field %r not permitted." % name)
FieldError: Join on field 'marker' not permitted. Did you misspell 'within' for the lookup type?
</module>

Обратите внимание, что

Location.objects.filter(marker__within=poly)

работает как ожидалось

Есть ли способ сделать это через отношения?

1 ответ

Получается, что ответ был указан в почтовом списке geodjango (https://groups.google.com/forum/?fromgroups=#!topic/geodjango/wvEJaYX_Cuc), поэтому я напишу здесь, если кто-то наткнулся на него

Если вам нужно использовать geoQueryset для отношения span, вам нужно использовать GeoManager также в модели, которая не имеет пространственной функции, а ForeignKey - для моделей с атрибутом как классом.

Поэтому правильный путь   из моделей импорта django.contrib.gis.db

class Location(models.Model):
 name = models.CharField(max_length=32,)
 marker = models.PointField(srid=4326) # the marker
 objects = models.GeoManager()
class Item(models.Model):
 name = models.CharField(max_length=200)
 location = models.ForeignKey(Location)
 objects = models.GeoManager()

а затем Item.objects.filter(location__marker__within=poly) работает так, как ожидалось.

licensed under cc by-sa 3.0 with attribution.