Request filtering using the django geographic range relationship is not accepted

I am trying to filter out an element using the geographic span relationship with geodjango, but I do not understand why it does not work. Consider this example:

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

If I request ("Location" is an existing place in db)

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

it works.

If instead I ask

 Item.objects.filter(location__marker__within=poly) 

I get this error

 --------------------------------------------------------------------------- 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? 

note that

 Location.objects.filter(marker__within=poly) 

works as expected

Is there a way to do this through relationships?

+4
source share
1 answer

It turns out that the answer was indicated in the geodjango mail list ( https://groups.google.com/forum/?fromgroups=#!topic/geodjango/wvEJaYX_Cuc ), so I will write here if someone came across it

If you need to use geoQueryset for a span relationship, you need to use GeoManager also in a model that does not have a spatial function, and ForeignKey for models with an attribute as a class.

Therefore, the correct path from the django.contrib.gis.db import models

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

and then Item.objects.filter(location__marker__within=poly) works as expected.

+6
source

Source: https://habr.com/ru/post/1441608/


All Articles