mirror of
https://github.com/django/django.git
synced 2025-06-05 11:39:13 +00:00
Fixed #15271 -- Defined a to_python method for GeometryField
Thanks volrath and copelco for their work on the patch.
This commit is contained in:
parent
45a1a54b0b
commit
41eb70f762
@ -5,7 +5,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||||||
|
|
||||||
# While this couples the geographic forms to the GEOS library,
|
# While this couples the geographic forms to the GEOS library,
|
||||||
# it decouples from database (by not importing SpatialBackend).
|
# 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):
|
class GeometryField(forms.Field):
|
||||||
"""
|
"""
|
||||||
@ -31,6 +31,15 @@ class GeometryField(forms.Field):
|
|||||||
self.null = kwargs.pop('null', True)
|
self.null = kwargs.pop('null', True)
|
||||||
super(GeometryField, self).__init__(**kwargs)
|
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):
|
def clean(self, value):
|
||||||
"""
|
"""
|
||||||
Validates that the input value can be converted to a Geometry
|
Validates that the input value can be converted to a Geometry
|
||||||
@ -44,11 +53,8 @@ class GeometryField(forms.Field):
|
|||||||
else:
|
else:
|
||||||
raise forms.ValidationError(self.error_messages['no_geom'])
|
raise forms.ValidationError(self.error_messages['no_geom'])
|
||||||
|
|
||||||
# Trying to create a Geometry object from the form value.
|
# Transform the value to a python object first
|
||||||
try:
|
geom = self.to_python(value)
|
||||||
geom = GEOSGeometry(value)
|
|
||||||
except:
|
|
||||||
raise forms.ValidationError(self.error_messages['invalid_geom'])
|
|
||||||
|
|
||||||
# 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).
|
||||||
|
@ -56,8 +56,25 @@ class GeometryFieldTest(unittest.TestCase):
|
|||||||
|
|
||||||
pnt_fld = forms.GeometryField(geom_type='POINT')
|
pnt_fld = forms.GeometryField(geom_type='POINT')
|
||||||
self.assertEqual(GEOSGeometry('POINT(5 23)'), pnt_fld.clean('POINT(5 23)'))
|
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)')
|
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():
|
def suite():
|
||||||
s = unittest.TestSuite()
|
s = unittest.TestSuite()
|
||||||
s.addTest(unittest.makeSuite(GeometryFieldTest))
|
s.addTest(unittest.makeSuite(GeometryFieldTest))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user