Opened 15 months ago

Closed 5 months ago

Last modified 2 months ago

#22352 closed New feature (wontfix)

GeoQuerySet methods: support lookups on reversed o2o relationships as field_name

Reported by: pchiquet Owned by: anonymous
Component: GIS Version: master
Severity: Normal Keywords: geodjango, GeoQuerySet
Cc: mmitar@…, jernej@… Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

GeoQuerySet methods, for example distance, are performed on a given geographic field of the model.

The geographic field to use can be specified thanks the field_name argument. field_name can be a field directly in the model or a lookup to a related field in another model (such as, 'address__point'). However lookups with reversed one to one relation are not supported.

For example, with the following model:

class User(Model):
    pass

class UserProfile(NamedModel):
    user = models.OneToOneField(User)
    point = models.PointField()

the following spatial operation on User fails:

  User.objects.all().distance(Point(1,1), field_name='userlocation__point')

and raises the following exception:

  Traceback (most recent call last):
    (...)
    File "django/contrib/gis/db/models/query.py", line 104, in distance
      return self._distance_attribute('distance', geom, **kwargs)
    File "django/contrib/gis/db/models/query.py", line 593, in _distance_attribute
      procedure_args, geo_field = self._spatial_setup(func, field_name=kwargs.get('field_name', None))
    File "django/contrib/gis/db/models/query.py", line 466, in _spatial_setup
      raise TypeError('%s output only available on GeometryFields.' % func)
  TypeError: ST_Distance output only available on GeometryFields.

The lookup is supported only if the foreign key is in the Queryset model. I think it would be nice to support reversed relations too.

Change History (14)

comment:1 Changed 15 months ago by Pierre Chiquet

  • Needs documentation unset
  • Needs tests unset
  • Owner changed from nobody to anonymous
  • Patch needs improvement unset
  • Status changed from new to assigned

comment:3 Changed 14 months ago by bmispelon

  • Triage Stage changed from Unreviewed to Accepted
  • Type changed from Bug to New feature

Hi,

This seems like a sensible feature to have so I'll move the ticket to "accepted".
The next step is to find someone familiar with the GIS codebase to review your patch and move the ticket to "ready for checkin".

Thanks.

comment:4 Changed 11 months ago by amirrustam

I think the request should also support reverse OneToMany relationships. This Stackoverflow question is relevant: http://stackoverflow.com/questions/25047964/geodjango-geoqueryset-distance-results-in-st-distance-output-only-available-o

comment:5 Changed 6 months ago by timgraham

  • Patch needs improvement set

This will require some changes after the _meta refactor branch is merged. Please send a pull request if you can update your patch after that.

comment:6 Changed 6 months ago by mitar

  • Cc mmitar@… added

comment:7 Changed 6 months ago by kostko

  • Cc jernej@… added

comment:8 Changed 6 months ago by mitar

This would be really cool to have. Including the OneToMany support.

comment:9 Changed 5 months ago by claudep

  • Resolution set to wontfix
  • Status changed from assigned to closed

I have tested this with my branch which replaces GeoQuerySet methods by model functions (#24214). And this was not a problem at all, be it with OneToOne or with OneToMany relations. The syntax will be User.objects.all().annotate(dist=distance('userlocation__point', Point(1,1)))

I'll close this one as won't fix, as I think it is not worth working on to-be-deprecated code. The aforementioned branch is waiting for someone knowledgeable with Oracle GIS to write the Oracle support.

comment:10 Changed 2 months ago by artscoop

The model functions are to be introduced in Django 1.9, and the to-be-deprecated code is still present in Django 1.8 (with LTS). I'm convinced a wontfix is not a good move here.

comment:11 Changed 2 months ago by claudep

Sorry, but unless this is a regression, it has no chance to enter Django 1.8.

comment:12 Changed 2 months ago by claudep

Also note that if you really need this functionality, it might be possible to adapt [d9ff5ef36d3f714736d633435d45f03eac9c17b5] to make it a third-party app usable from Django 1.8.

comment:13 Changed 2 months ago by artscoop

This may not be a regression, but I'm sure it's a bug. The field_name exposes the possibility to span across relationships. It works with ForeignKeys, but not with OneToOneFields, which does not make much sense. (The bug occurs because of the way the "field__field__etc" relationship span is processed).
If a fix won't make it to Django 1.8, I'm going to backport the lookup functions to a third party app as suggested.

Last edited 2 months ago by artscoop (previous) (diff)

comment:14 Changed 2 months ago by timgraham

If it's not a regression from a previous release or a major bug in a new feature it won't be backported. See our supported versions policy.

Note: See TracTickets for help on using tickets.
Back to Top