diff --git a/django/contrib/gis/forms/fields.py b/django/contrib/gis/forms/fields.py index d05518c971..269981048d 100644 --- a/django/contrib/gis/forms/fields.py +++ b/django/contrib/gis/forms/fields.py @@ -1,4 +1,5 @@ from django import forms +from django.contrib.gis.gdal import GDALException from django.contrib.gis.geos import GEOSException, GEOSGeometry from django.utils.translation import gettext_lazy as _ @@ -36,7 +37,10 @@ class GeometryField(forms.Field): if not isinstance(value, GEOSGeometry): if hasattr(self.widget, 'deserialize'): - value = self.widget.deserialize(value) + try: + value = self.widget.deserialize(value) + except GDALException: + value = None else: try: value = GEOSGeometry(value) diff --git a/tests/gis_tests/test_geoforms.py b/tests/gis_tests/test_geoforms.py index 73933b992d..dfb2e9e9e1 100644 --- a/tests/gis_tests/test_geoforms.py +++ b/tests/gis_tests/test_geoforms.py @@ -69,19 +69,31 @@ class GeometryFieldTest(SimpleTestCase): def test_to_python(self): """ - Testing to_python returns a correct GEOSGeometry object or - a ValidationError + to_python() either returns a correct GEOSGeometry object or + a ValidationError. """ + good_inputs = [ + 'POINT(5 23)', + 'MULTIPOLYGON(((0 0, 0 1, 1 1, 1 0, 0 0)))', + 'LINESTRING(0 0, 1 1)', + ] + bad_inputs = [ + 'POINT(5)', + 'MULTI POLYGON(((0 0, 0 1, 1 1, 1 0, 0 0)))', + 'BLAH(0 0, 1 1)', + '{"type": "FeatureCollection", "features": [' + '{"geometry": {"type": "Point", "coordinates": [508375, 148905]}, "type": "Feature"}]}', + ] 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)'): - with self.subTest(wkt=wkt): - self.assertEqual(GEOSGeometry(wkt, srid=fld.widget.map_srid), fld.to_python(wkt)) + for geo_input in good_inputs: + with self.subTest(geo_input=geo_input): + self.assertEqual(GEOSGeometry(geo_input, srid=fld.widget.map_srid), fld.to_python(geo_input)) # 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)'): - with self.subTest(wkt=wkt): + for geo_input in bad_inputs: + with self.subTest(geo_input=geo_input): with self.assertRaises(forms.ValidationError): - fld.to_python(wkt) + fld.to_python(geo_input) def test_to_python_different_map_srid(self): f = forms.GeometryField(widget=OpenLayersWidget)