summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaude Paroz <claude@2xlibre.net>2012-06-19 14:55:40 +0200
committerClaude Paroz <claude@2xlibre.net>2012-06-19 14:55:40 +0200
commit41eb70f7620dbae43bb72f265489fa3ac19c5c66 (patch)
tree55a540359cf640e65493d513d95184cbfee982c1
parent45a1a54b0b234996a9880bd89924df2aa86b8f9a (diff)
Fixed #15271 -- Defined a to_python method for GeometryField
Thanks volrath and copelco for their work on the patch.
-rw-r--r--django/contrib/gis/forms/fields.py18
-rw-r--r--django/contrib/gis/tests/test_geoforms.py17
2 files changed, 29 insertions, 6 deletions
diff --git a/django/contrib/gis/forms/fields.py b/django/contrib/gis/forms/fields.py
index 432f0e1872..cefb6830ba 100644
--- a/django/contrib/gis/forms/fields.py
+++ b/django/contrib/gis/forms/fields.py
@@ -5,7 +5,7 @@ from django.utils.translation import ugettext_lazy as _
# While this couples the geographic forms to the GEOS library,
# it decouples from database (by not importing SpatialBackend).
-from django.contrib.gis.geos import GEOSGeometry
+from django.contrib.gis.geos import GEOSException, GEOSGeometry
class GeometryField(forms.Field):
"""
@@ -31,6 +31,15 @@ class GeometryField(forms.Field):
self.null = kwargs.pop('null', True)
super(GeometryField, self).__init__(**kwargs)
+ def to_python(self, value):
+ """
+ Transforms the value to a Geometry object.
+ """
+ try:
+ return GEOSGeometry(value)
+ except (GEOSException, ValueError, TypeError):
+ raise forms.ValidationError(self.error_messages['invalid_geom'])
+
def clean(self, value):
"""
Validates that the input value can be converted to a Geometry
@@ -44,11 +53,8 @@ class GeometryField(forms.Field):
else:
raise forms.ValidationError(self.error_messages['no_geom'])
- # Trying to create a Geometry object from the form value.
- try:
- geom = GEOSGeometry(value)
- except:
- raise forms.ValidationError(self.error_messages['invalid_geom'])
+ # Transform the value to a python object first
+ geom = self.to_python(value)
# Ensuring that the geometry is of the correct type (indicated
# using the OGC string label).
diff --git a/django/contrib/gis/tests/test_geoforms.py b/django/contrib/gis/tests/test_geoforms.py
index 9d2b7c7c3c..ed851df0d2 100644
--- a/django/contrib/gis/tests/test_geoforms.py
+++ b/django/contrib/gis/tests/test_geoforms.py
@@ -56,8 +56,25 @@ class GeometryFieldTest(unittest.TestCase):
pnt_fld = forms.GeometryField(geom_type='POINT')
self.assertEqual(GEOSGeometry('POINT(5 23)'), pnt_fld.clean('POINT(5 23)'))
+ # a WKT for any other geom_type will be properly transformed by `to_python`
+ self.assertEqual(GEOSGeometry('LINESTRING(0 0, 1 1)'), pnt_fld.to_python('LINESTRING(0 0, 1 1)'))
+ # but rejected by `clean`
self.assertRaises(forms.ValidationError, pnt_fld.clean, 'LINESTRING(0 0, 1 1)')
+ def test04_to_python(self):
+ """
+ Testing to_python returns a correct GEOSGeometry object or
+ a ValidationError
+ """
+ fld = forms.GeometryField()
+ # to_python returns the same GEOSGeometry for a WKT
+ for wkt in ('POINT(5 23)', 'MULTIPOLYGON(((0 0, 0 1, 1 1, 1 0, 0 0)))', 'LINESTRING(0 0, 1 1)'):
+ self.assertEqual(GEOSGeometry(wkt), fld.to_python(wkt))
+ # but raises a ValidationError for any other string
+ for wkt in ('POINT(5)', 'MULTI POLYGON(((0 0, 0 1, 1 1, 1 0, 0 0)))', 'BLAH(0 0, 1 1)'):
+ self.assertRaises(forms.ValidationError, fld.to_python, wkt)
+
+
def suite():
s = unittest.TestSuite()
s.addTest(unittest.makeSuite(GeometryFieldTest))