Fixed #26789 -- Fixed handling of empty geometries in BaseSpatialField.get_db_prep_save().

This commit is contained in:
Sergey Fedoseev 2016-06-17 20:03:50 +05:00 committed by Tim Graham
parent b90d72facf
commit 183f501540
4 changed files with 31 additions and 5 deletions

View File

@ -26,6 +26,8 @@ class BaseSpatialFeatures(object):
supports_real_shape_operations = True supports_real_shape_operations = True
# Can geometry fields be null? # Can geometry fields be null?
supports_null_geometries = True supports_null_geometries = True
# Are empty geometries supported?
supports_empty_geometries = False
# Can the the function be applied on geodetic coordinate systems? # Can the the function be applied on geodetic coordinate systems?
supports_distance_geodetic = True supports_distance_geodetic = True
supports_length_geodetic = True supports_length_geodetic = True

View File

@ -8,3 +8,4 @@ class DatabaseFeatures(BaseSpatialFeatures, Psycopg2DatabaseFeatures):
supports_3d_functions = True supports_3d_functions = True
supports_left_right_lookups = True supports_left_right_lookups = True
supports_raster = True supports_raster = True
supports_empty_geometries = True

View File

@ -177,10 +177,10 @@ class BaseSpatialField(Field):
""" """
Prepare the value for saving in the database. Prepare the value for saving in the database.
""" """
if not value: if isinstance(value, Geometry) or value:
return None
else:
return connection.ops.Adapter(self.get_prep_value(value)) return connection.ops.Adapter(self.get_prep_value(value))
else:
return None
def get_raster_prep_value(self, value, is_candidate): def get_raster_prep_value(self, value, is_candidate):
""" """

View File

@ -6,8 +6,8 @@ import tempfile
from django.contrib.gis import gdal from django.contrib.gis import gdal
from django.contrib.gis.db.models import Extent, MakeLine, Union from django.contrib.gis.db.models import Extent, MakeLine, Union
from django.contrib.gis.geos import ( from django.contrib.gis.geos import (
GeometryCollection, GEOSGeometry, LinearRing, LineString, Point, Polygon, GeometryCollection, GEOSGeometry, LinearRing, LineString, MultiLineString,
fromstr, MultiPoint, MultiPolygon, Point, Polygon, fromstr,
) )
from django.core.management import call_command from django.core.management import call_command
from django.db import connection from django.db import connection
@ -215,6 +215,29 @@ class GeoModelTest(TestCase):
call_command('loaddata', tmp.name, verbosity=0) call_command('loaddata', tmp.name, verbosity=0)
self.assertListEqual(original_data, list(City.objects.all().order_by('name'))) self.assertListEqual(original_data, list(City.objects.all().order_by('name')))
@skipUnlessDBFeature("supports_empty_geometries")
def test_empty_geometries(self):
geometry_classes = [
Point,
LineString,
LinearRing,
Polygon,
MultiPoint,
MultiLineString,
MultiPolygon,
GeometryCollection,
]
for klass in geometry_classes:
g = klass(srid=4326)
feature = Feature.objects.create(name='Empty %s' % klass.__name__, geom=g)
feature.refresh_from_db()
if klass is LinearRing:
# LinearRing isn't representable in WKB, so GEOSGeomtry.wkb
# uses LineString instead.
g = LineString(srid=4326)
self.assertEqual(feature.geom, g)
self.assertEqual(feature.geom.srid, g.srid)
@skipUnlessDBFeature("gis_enabled") @skipUnlessDBFeature("gis_enabled")
class GeoLookupTest(TestCase): class GeoLookupTest(TestCase):