#33638: Model Admin for GIS models cannot save model with point field when
(geography=True, unique=True) with postgis backend
--------------------------------------------+------------------------
               Reporter:  Sebastian Clarke  |          Owner:  nobody
                   Type:  Bug               |         Status:  new
              Component:  GIS               |        Version:  3.2
               Severity:  Normal            |       Keywords:
           Triage Stage:  Unreviewed        |      Has patch:  0
    Needs documentation:  0                 |    Needs tests:  0
Patch needs improvement:  0                 |  Easy pickings:  0
                  UI/UX:  0                 |
--------------------------------------------+------------------------
 If you define a model with a geometry point field that has geography=True
 and unique=True, the default admin interface generated for this model
 cannot save an existing instance.

 When you save, you ultimately hit the error:

 {{{
 ValueError: PostGIS geography does not support the "~=" function/operator.
 }}}

 This is caused by the `validate_unique()` method on the model instance.
 When performing unique checks (in `_perform_unique_checks()`), it's
 forming a queryset with `objects.filter(geometry=geometry)` and (as noted
 in related issue https://code.djangoproject.com/ticket/27314) that results
 in the ~= operator being used in PostGIS which is not supported on
 geographic geometries.

 We will work around this issue ourselves, by overriding
 `validate_unique()` on the model, passing the field in question to the
 exclude list in the super call, then doing our own manual check by instead
 using a filter like:

 {{{
 GeoModel.objects.filter(geometry__bboverlaps=point)
 }}}

 i.e., a bounding-box overlaps check.

 For point fields, the concept of even having a bounding box, and how much
 sense that makes, I suppose is up for debate (points theoretically being
 of infinitely small size). However this check performs in the way we want
 and works as you might expect the equality operator to.

 Have not confirmed whether the issue exists for geometry fields other than
 Point, or on versions other than 3.2 - but I strongly suspect so.

 Simplest test case would be to have a models.py:

 {{{
 from django.contrib.gis.db import models

 class Location(models.Model):
     geometry = models.PointField(geography=True, unique=True)
 }}}

 along with admin.py

 {{{
 from django.contrib.gis import admin
 admin.site.register(Location, admin.OSMGeoAdmin)
 }}}

 and then try and save an existing instance when using the postgis db
 backend.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/33638>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/010701801d2e6f9d-b3b7b340-ff21-46fa-8123-70d93ff52246-000000%40eu-central-1.amazonses.com.

Reply via email to