Commit 18e990fa authored by Claude Paroz's avatar Claude Paroz
Browse files

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

Thanks slinkp for the report and the initial patch.
parent a87ff951
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -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,
                    }
+12 −11
Original line number Diff line number Diff line
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).
+5 −6
Original line number Diff line number Diff line
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."