From 18e990fa9639b5476b556c8de82717ebfc8b254e Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Fri, 15 Mar 2013 21:45:33 +0100 Subject: [PATCH] Fixed #16110 -- Fixed GeometryField odd behaviour regarding null values Thanks slinkp for the report and the initial patch. --- django/contrib/gis/db/models/fields.py | 1 - django/contrib/gis/forms/fields.py | 23 ++++++++++++----------- django/contrib/gis/tests/test_geoforms.py | 11 +++++------ 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/django/contrib/gis/db/models/fields.py b/django/contrib/gis/db/models/fields.py index d90ce309d4..249617f771 100644 --- a/django/contrib/gis/db/models/fields.py +++ b/django/contrib/gis/db/models/fields.py @@ -202,7 +202,6 @@ class GeometryField(Field): def formfield(self, **kwargs): defaults = {'form_class' : forms.GeometryField, - 'null' : self.null, 'geom_type' : self.geom_type, 'srid' : self.srid, } diff --git a/django/contrib/gis/forms/fields.py b/django/contrib/gis/forms/fields.py index ab2e37f1e1..d3feac83e7 100644 --- a/django/contrib/gis/forms/fields.py +++ b/django/contrib/gis/forms/fields.py @@ -1,5 +1,7 @@ from __future__ import unicode_literals +import warnings + from django import forms from django.utils import six from django.utils.translation import ugettext_lazy as _ @@ -18,7 +20,7 @@ class GeometryField(forms.Field): widget = forms.Textarea default_error_messages = { - 'no_geom' : _('No geometry value provided.'), + 'required' : _('No geometry value provided.'), 'invalid_geom' : _('Invalid geometry value.'), 'invalid_geom_type' : _('Invalid geometry type.'), 'transform_error' : _('An error occurred when transforming the geometry ' @@ -30,13 +32,18 @@ class GeometryField(forms.Field): # defaults (e.g., allow None). self.srid = kwargs.pop('srid', None) self.geom_type = kwargs.pop('geom_type', 'GEOMETRY') - self.null = kwargs.pop('null', True) + if 'null' in kwargs: + kwargs.pop('null', True) + warnings.warn("Passing 'null' keyword argument to GeometryField is deprecated.", + DeprecationWarning, stacklevel=2) super(GeometryField, self).__init__(**kwargs) def to_python(self, value): """ Transforms the value to a Geometry object. """ + if value in self.empty_values: + return None try: return GEOSGeometry(value) except (GEOSException, ValueError, TypeError): @@ -48,15 +55,9 @@ class GeometryField(forms.Field): object (which is returned). A ValidationError is raised if the value cannot be instantiated as a Geometry. """ - if not value: - if self.null and not self.required: - # The geometry column allows NULL and is not required. - return None - else: - raise forms.ValidationError(self.error_messages['no_geom']) - - # Transform the value to a python object first - geom = self.to_python(value) + geom = super(GeometryField, self).clean(value) + if geom is None: + return geom # 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 ed851df0d2..24bb50c6bc 100644 --- a/django/contrib/gis/tests/test_geoforms.py +++ b/django/contrib/gis/tests/test_geoforms.py @@ -1,6 +1,7 @@ from django.forms import ValidationError from django.contrib.gis.gdal import HAS_GDAL from django.contrib.gis.tests.utils import HAS_SPATIALREFSYS +from django.utils import six from django.utils import unittest @@ -37,15 +38,13 @@ class GeometryFieldTest(unittest.TestCase): "Testing GeometryField's handling of null (None) geometries." # Form fields, by default, are required (`required=True`) fld = forms.GeometryField() - self.assertRaises(forms.ValidationError, fld.clean, None) - - # Still not allowed if `null=False`. - fld = forms.GeometryField(required=False, null=False) - self.assertRaises(forms.ValidationError, fld.clean, None) + with six.assertRaisesRegex(self, forms.ValidationError, + "No geometry value provided."): + fld.clean(None) # This will clean None as a geometry (See #10660). fld = forms.GeometryField(required=False) - self.assertEqual(None, fld.clean(None)) + self.assertIsNone(fld.clean(None)) def test03_geom_type(self): "Testing GeometryField's handling of different geometry types."