Fixed #16110 -- Fixed GeometryField odd behaviour regarding null values

Thanks slinkp for the report and the initial patch.
This commit is contained in:
Claude Paroz 2013-03-15 21:45:33 +01:00
parent a87ff951b6
commit 18e990fa96
3 changed files with 17 additions and 18 deletions

View File

@ -202,7 +202,6 @@ class GeometryField(Field):
def formfield(self, **kwargs): def formfield(self, **kwargs):
defaults = {'form_class' : forms.GeometryField, defaults = {'form_class' : forms.GeometryField,
'null' : self.null,
'geom_type' : self.geom_type, 'geom_type' : self.geom_type,
'srid' : self.srid, 'srid' : self.srid,
} }

View File

@ -1,5 +1,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import warnings
from django import forms from django import forms
from django.utils import six from django.utils import six
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -18,7 +20,7 @@ class GeometryField(forms.Field):
widget = forms.Textarea widget = forms.Textarea
default_error_messages = { default_error_messages = {
'no_geom' : _('No geometry value provided.'), 'required' : _('No geometry value provided.'),
'invalid_geom' : _('Invalid geometry value.'), 'invalid_geom' : _('Invalid geometry value.'),
'invalid_geom_type' : _('Invalid geometry type.'), 'invalid_geom_type' : _('Invalid geometry type.'),
'transform_error' : _('An error occurred when transforming the geometry ' 'transform_error' : _('An error occurred when transforming the geometry '
@ -30,13 +32,18 @@ class GeometryField(forms.Field):
# defaults (e.g., allow None). # defaults (e.g., allow None).
self.srid = kwargs.pop('srid', None) self.srid = kwargs.pop('srid', None)
self.geom_type = kwargs.pop('geom_type', 'GEOMETRY') 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) super(GeometryField, self).__init__(**kwargs)
def to_python(self, value): def to_python(self, value):
""" """
Transforms the value to a Geometry object. Transforms the value to a Geometry object.
""" """
if value in self.empty_values:
return None
try: try:
return GEOSGeometry(value) return GEOSGeometry(value)
except (GEOSException, ValueError, TypeError): except (GEOSException, ValueError, TypeError):
@ -48,15 +55,9 @@ class GeometryField(forms.Field):
object (which is returned). A ValidationError is raised if object (which is returned). A ValidationError is raised if
the value cannot be instantiated as a Geometry. the value cannot be instantiated as a Geometry.
""" """
if not value: geom = super(GeometryField, self).clean(value)
if self.null and not self.required: if geom is None:
# The geometry column allows NULL and is not required. return geom
return None
else:
raise forms.ValidationError(self.error_messages['no_geom'])
# Transform the value to a python object first
geom = self.to_python(value)
# Ensuring that the geometry is of the correct type (indicated # Ensuring that the geometry is of the correct type (indicated
# using the OGC string label). # using the OGC string label).

View File

@ -1,6 +1,7 @@
from django.forms import ValidationError from django.forms import ValidationError
from django.contrib.gis.gdal import HAS_GDAL from django.contrib.gis.gdal import HAS_GDAL
from django.contrib.gis.tests.utils import HAS_SPATIALREFSYS from django.contrib.gis.tests.utils import HAS_SPATIALREFSYS
from django.utils import six
from django.utils import unittest from django.utils import unittest
@ -37,15 +38,13 @@ class GeometryFieldTest(unittest.TestCase):
"Testing GeometryField's handling of null (None) geometries." "Testing GeometryField's handling of null (None) geometries."
# Form fields, by default, are required (`required=True`) # Form fields, by default, are required (`required=True`)
fld = forms.GeometryField() fld = forms.GeometryField()
self.assertRaises(forms.ValidationError, fld.clean, None) with six.assertRaisesRegex(self, forms.ValidationError,
"No geometry value provided."):
# Still not allowed if `null=False`. fld.clean(None)
fld = forms.GeometryField(required=False, null=False)
self.assertRaises(forms.ValidationError, fld.clean, None)
# This will clean None as a geometry (See #10660). # This will clean None as a geometry (See #10660).
fld = forms.GeometryField(required=False) fld = forms.GeometryField(required=False)
self.assertEqual(None, fld.clean(None)) self.assertIsNone(fld.clean(None))
def test03_geom_type(self): def test03_geom_type(self):
"Testing GeometryField's handling of different geometry types." "Testing GeometryField's handling of different geometry types."