Browse Source

Fixed #21003 -- Ensured geometry widget return value has SRID

Thanks Mathieu Leplatre for the report and initial patch.
Claude Paroz 11 years ago
parent
commit
dd656073ad

+ 14 - 11
django/contrib/gis/forms/fields.py

@@ -41,10 +41,15 @@ class GeometryField(forms.Field):
         """
         if value in self.empty_values:
             return None
-        try:
-            return GEOSGeometry(value)
-        except (GEOSException, ValueError, TypeError):
-            raise forms.ValidationError(self.error_messages['invalid_geom'], code='invalid_geom')
+
+        if not isinstance(value, GEOSGeometry):
+            try:
+                value = GEOSGeometry(value)
+                if not value.srid:
+                    value.srid = self.widget.map_srid
+            except (GEOSException, ValueError, TypeError):
+                raise forms.ValidationError(self.error_messages['invalid_geom'], code='invalid_geom')
+        return value
 
     def clean(self, value):
         """
@@ -77,16 +82,14 @@ class GeometryField(forms.Field):
     def _has_changed(self, initial, data):
         """ Compare geographic value of data with its initial value. """
 
-        # Ensure we are dealing with a geographic object
-        if isinstance(initial, six.string_types):
-            try:
-                initial = GEOSGeometry(initial)
-            except (GEOSException, ValueError):
-                initial = None
+        try:
+            data = self.to_python(data)
+            initial = self.to_python(initial)
+        except ValidationError:
+            return True
 
         # Only do a geographic comparison if both values are available
         if initial and data:
-            data = fromstr(data)
             data.transform(initial.srid)
             # If the initial value was not added by the browser, the geometry
             # provided may be slightly different, the first time it is saved.

+ 1 - 1
django/contrib/gis/forms/widgets.py

@@ -39,7 +39,7 @@ class BaseGeometryWidget(Widget):
 
     def deserialize(self, value):
         try:
-            return GEOSGeometry(value)
+            return GEOSGeometry(value, self.map_srid)
         except (GEOSException, ValueError) as err:
             logger.error(
                 "Error creating geometry from value '%s' (%s)" % (

+ 5 - 0
django/contrib/gis/tests/test_geoforms.py

@@ -282,3 +282,8 @@ class CustomGeometryWidgetTest(SimpleTestCase):
         # Force deserialize use due to a string value
         self.assertIn(escape(point.json), widget.render('p', point.json))
         self.assertEqual(widget.deserialize_called, 1)
+
+        form = PointForm(data={'p': point.json})
+        self.assertTrue(form.is_valid())
+        # Ensure that resulting geometry has srid set
+        self.assertEqual(form.cleaned_data['p'].srid, 4326)