summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Fedoseev <fedoseev.sergey@gmail.com>2016-06-17 20:03:50 +0500
committerTim Graham <timograham@gmail.com>2016-12-06 13:58:22 -0500
commit183f5015408ffe0d3a22203ddaf7a3a56da025fd (patch)
treee0c7c7bde6fc7e41a95b3167d5d6213c456a7d2d
parentb90d72facf1e4294df1c2e6b51b26f6879bf2992 (diff)
Fixed #26789 -- Fixed handling of empty geometries in BaseSpatialField.get_db_prep_save().
-rw-r--r--django/contrib/gis/db/backends/base/features.py2
-rw-r--r--django/contrib/gis/db/backends/postgis/features.py1
-rw-r--r--django/contrib/gis/db/models/fields.py6
-rw-r--r--tests/gis_tests/geoapp/tests.py27
4 files changed, 31 insertions, 5 deletions
diff --git a/django/contrib/gis/db/backends/base/features.py b/django/contrib/gis/db/backends/base/features.py
index 451b515625..3d1dfba1dd 100644
--- a/django/contrib/gis/db/backends/base/features.py
+++ b/django/contrib/gis/db/backends/base/features.py
@@ -26,6 +26,8 @@ class BaseSpatialFeatures(object):
supports_real_shape_operations = True
# Can geometry fields be null?
supports_null_geometries = True
+ # Are empty geometries supported?
+ supports_empty_geometries = False
# Can the the function be applied on geodetic coordinate systems?
supports_distance_geodetic = True
supports_length_geodetic = True
diff --git a/django/contrib/gis/db/backends/postgis/features.py b/django/contrib/gis/db/backends/postgis/features.py
index ea1d450008..2d613efe6e 100644
--- a/django/contrib/gis/db/backends/postgis/features.py
+++ b/django/contrib/gis/db/backends/postgis/features.py
@@ -8,3 +8,4 @@ class DatabaseFeatures(BaseSpatialFeatures, Psycopg2DatabaseFeatures):
supports_3d_functions = True
supports_left_right_lookups = True
supports_raster = True
+ supports_empty_geometries = True
diff --git a/django/contrib/gis/db/models/fields.py b/django/contrib/gis/db/models/fields.py
index a3813edd58..7519b30fb2 100644
--- a/django/contrib/gis/db/models/fields.py
+++ b/django/contrib/gis/db/models/fields.py
@@ -177,10 +177,10 @@ class BaseSpatialField(Field):
"""
Prepare the value for saving in the database.
"""
- if not value:
- return None
- else:
+ if isinstance(value, Geometry) or value:
return connection.ops.Adapter(self.get_prep_value(value))
+ else:
+ return None
def get_raster_prep_value(self, value, is_candidate):
"""
diff --git a/tests/gis_tests/geoapp/tests.py b/tests/gis_tests/geoapp/tests.py
index aede5950cd..9d03d6ff78 100644
--- a/tests/gis_tests/geoapp/tests.py
+++ b/tests/gis_tests/geoapp/tests.py
@@ -6,8 +6,8 @@ import tempfile
from django.contrib.gis import gdal
from django.contrib.gis.db.models import Extent, MakeLine, Union
from django.contrib.gis.geos import (
- GeometryCollection, GEOSGeometry, LinearRing, LineString, Point, Polygon,
- fromstr,
+ GeometryCollection, GEOSGeometry, LinearRing, LineString, MultiLineString,
+ MultiPoint, MultiPolygon, Point, Polygon, fromstr,
)
from django.core.management import call_command
from django.db import connection
@@ -215,6 +215,29 @@ class GeoModelTest(TestCase):
call_command('loaddata', tmp.name, verbosity=0)
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")
class GeoLookupTest(TestCase):