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

Thanks Mathieu Leplatre for the report and initial patch.
This commit is contained in:
Claude Paroz 2013-09-03 13:51:55 +02:00
parent 3550b27a89
commit dd656073ad
3 changed files with 20 additions and 12 deletions

View File

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

View File

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

View File

@ -282,3 +282,8 @@ class CustomGeometryWidgetTest(SimpleTestCase):
# Force deserialize use due to a string value # Force deserialize use due to a string value
self.assertIn(escape(point.json), widget.render('p', point.json)) self.assertIn(escape(point.json), widget.render('p', point.json))
self.assertEqual(widget.deserialize_called, 1) 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)