"parcel" is a foreign key to the geometry model information:
class Parcel(models.Model,models.GeoMixin): gid = models.IntegerField(db_column='gid',primary_key=True) apn = models.CharField(db_column='apn',maxlength=10) poly = models.PolygonField(db_column='the_geom',srid=4269, index=True) zip = models.CharField(db_column='zip', maxlength=5) objects = models.GeoManager()
I can do spatial queries if they are directly between two models with polygon fields but I can't seem to get at the spatial queries through foreign keys.
Traceback (most recent call last): File "<console>", line 1, in <module> File "/Library/Frameworks/Python.framework/Versions/2.5/lib/ python2.5/site-packages/django_gis/django/db/models/query.py", line 102, in __repr__ return repr(self._get_data()) File "/Library/Frameworks/Python.framework/Versions/2.5/lib/ python2.5/site-packages/django_gis/django/db/models/query.py", line 470, in _get_data self._result_cache = list(self.iterator()) File "/Library/Frameworks/Python.framework/Versions/2.5/lib/ python2.5/site-packages/django_gis/django/db/models/query.py", line 174, in iterator select, sql, params = self._get_sql_clause() File "/Library/Frameworks/Python.framework/Versions/2.5/lib/ python2.5/site-packages/django_gis/django/db/models/query.py", line 484, in _get_sql_clause joins2, where2, params2 = self._filters.get_sql(opts) File "/Library/Frameworks/Python.framework/Versions/2.5/lib/ python2.5/site-packages/django_gis/django/db/models/query.py", line 648, in get_sql joins2, where2, params2 = val.get_sql(opts) File "/Library/Frameworks/Python.framework/Versions/2.5/lib/ python2.5/site-packages/django_gis/django/db/models/query.py", line 699, in get_sql return parse_lookup(self.kwargs.items(), opts) File "/Library/Frameworks/Python.framework/Versions/2.5/lib/ python2.5/site-packages/django_gis/django/db/models/query.py", line 831, in parse_lookup joins2, where2, params2 = lookup_inner(path, lookup_type, value, opts, opts.db_table, None) File "/Library/Frameworks/Python.framework/Versions/2.5/lib/ python2.5/site-packages/django_gis/django/db/models/query.py", line 970, in lookup_inner joins2, where2, params2 = lookup_inner(path, lookup_type, value, new_opts, new_table, join_column) File "/Library/Frameworks/Python.framework/Versions/2.5/lib/ python2.5/site-packages/django_gis/django/db/models/query.py", line 938, in lookup_inner raise TypeError, "Cannot resolve keyword '%s' into field" % name TypeError: Cannot resolve keyword 'poly__contained' into field
I wouldn't think this would actually work but I just put the objects = models.GeoManager() on my model and it now knows what to do with the spatial queries. Excellent.
On 4/17/07, mattxbart <mattxb...@gmail.com> wrote:
> I can do spatial queries if they are directly between two models with > polygon fields but I can't seem to get at the spatial queries through > foreign keys.
> Traceback (most recent call last): > File "<console>", line 1, in <module> > File "/Library/Frameworks/Python.framework/Versions/2.5/lib/ > python2.5/site-packages/django_gis/django/db/models/query.py", line > 102, in __repr__ > return repr(self._get_data()) > File "/Library/Frameworks/Python.framework/Versions/2.5/lib/ > python2.5/site-packages/django_gis/django/db/models/query.py", line > 470, in _get_data > self._result_cache = list(self.iterator()) > File "/Library/Frameworks/Python.framework/Versions/2.5/lib/ > python2.5/site-packages/django_gis/django/db/models/query.py", line > 174, in iterator > select, sql, params = self._get_sql_clause() > File "/Library/Frameworks/Python.framework/Versions/2.5/lib/ > python2.5/site-packages/django_gis/django/db/models/query.py", line > 484, in _get_sql_clause > joins2, where2, params2 = self._filters.get_sql(opts) > File "/Library/Frameworks/Python.framework/Versions/2.5/lib/ > python2.5/site-packages/django_gis/django/db/models/query.py", line > 648, in get_sql > joins2, where2, params2 = val.get_sql(opts) > File "/Library/Frameworks/Python.framework/Versions/2.5/lib/ > python2.5/site-packages/django_gis/django/db/models/query.py", line > 699, in get_sql > return parse_lookup(self.kwargs.items(), opts) > File "/Library/Frameworks/Python.framework/Versions/2.5/lib/ > python2.5/site-packages/django_gis/django/db/models/query.py", line > 831, in parse_lookup > joins2, where2, params2 = lookup_inner(path, lookup_type, value, > opts, opts.db_table, None) > File "/Library/Frameworks/Python.framework/Versions/2.5/lib/ > python2.5/site-packages/django_gis/django/db/models/query.py", line > 970, in lookup_inner > joins2, where2, params2 = lookup_inner(path, lookup_type, value, > new_opts, new_table, join_column) > File "/Library/Frameworks/Python.framework/Versions/2.5/lib/ > python2.5/site-packages/django_gis/django/db/models/query.py", line > 938, in lookup_inner > raise TypeError, "Cannot resolve keyword '%s' into field" % name > TypeError: Cannot resolve keyword 'poly__contained' into field
That's a good point you brought up: if there's a ForeignKey to a model with a geographic field, then the model with the ForeignKey requires GeoManager to construct geographic queries on related objects (even if the model itself does not have geographic fields).
The GeoManager overrides the regular Manager to return GeoQuerySet objects (instead of QuerySet). The GeoQuerySet objects have their own parse_lookup() function that constructs the SQL for the geographic queries. While its almost verbatim from the 'original' parse_lookup() in django/db/models/query.py, it has a few changes that allow it to use the PostGIS lookup types. Thus, when you have no GeoManager, the regular Manager is used and it has no clue what to do with the geographic lookup types. Therefore, GeoManager needs to be used whenever geographic queries are needed.
I'll try and put something in the GeoDjango FAQ about this. Thanks for posting your experience and solution.