Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Removed some more hardcoded backends in GIS tests

Refs #22632. Thanks Tim Graham for the review.
  • Loading branch information...
commit 60428ed5db76f509f4a0eb737d96b4f0ae6b0ad5 1 parent 5675eb3
@claudep claudep authored
View
27 django/contrib/gis/db/backends/base.py
@@ -16,6 +16,9 @@ class BaseSpatialFeatures(object):
# Does the database contain a SpatialRefSys model to store SRID information?
has_spatialrefsys_table = True
+ # Reference implementation of 3D functions is:
+ # http://postgis.net/docs/PostGIS_Special_Functions_Index.html#PostGIS_3D_Functions
+ supports_3d_functions = False
# Does the database support SRID transform operations?
supports_transform = True
# Do geometric relationship operations operate on real shapes (or only on bounding boxes)?
@@ -29,24 +32,34 @@ class BaseSpatialFeatures(object):
# The following properties indicate if the database backend support
# certain lookups (dwithin, left and right, relate, ...)
+ supports_distances_lookups = True
supports_left_right_lookups = False
@property
- def supports_relate_lookup(self):
- return 'relate' in self.connection.ops.geometry_functions
+ def supports_bbcontains_lookup(self):
+ return 'bbcontains' in self.connection.ops.gis_terms
+
+ @property
+ def supports_contained_lookup(self):
+ return 'contained' in self.connection.ops.gis_terms
@property
- def has_dwithin_lookup(self):
+ def supports_dwithin_lookup(self):
return 'dwithin' in self.connection.ops.distance_functions
+ @property
+ def supports_relate_lookup(self):
+ return 'relate' in self.connection.ops.gis_terms
+
# For each of those methods, the class will have a property named
# `has_<name>_method` (defined in __init__) which accesses connection.ops
# to determine GIS method availability.
geoqueryset_methods = (
- 'centroid', 'difference', 'envelope', 'force_rhr', 'geohash', 'gml',
- 'intersection', 'kml', 'num_geom', 'perimeter', 'point_on_surface',
- 'reverse', 'scale', 'snap_to_grid', 'svg', 'sym_difference',
- 'transform', 'translate', 'union', 'unionagg',
+ 'area', 'centroid', 'difference', 'distance', 'distance_spheroid',
+ 'envelope', 'force_rhr', 'geohash', 'gml', 'intersection', 'kml',
+ 'length', 'num_geom', 'perimeter', 'point_on_surface', 'reverse',
+ 'scale', 'snap_to_grid', 'svg', 'sym_difference', 'transform',
+ 'translate', 'union', 'unionagg',
)
# Specifies whether the Collect and Extent aggregates are supported by the database
View
1  django/contrib/gis/db/backends/mysql/base.py
@@ -10,6 +10,7 @@
class DatabaseFeatures(BaseSpatialFeatures, MySQLDatabaseFeatures):
has_spatialrefsys_table = False
+ supports_distances_lookups = False
supports_transform = False
supports_real_shape_operations = False
supports_null_geometries = False
View
1  django/contrib/gis/db/backends/postgis/base.py
@@ -11,6 +11,7 @@
class DatabaseFeatures(BaseSpatialFeatures, Psycopg2DatabaseFeatures):
+ supports_3d_functions = True
supports_left_right_lookups = True
View
8 django/contrib/gis/db/models/query.py
@@ -631,8 +631,8 @@ def _distance_attribute(self, func, geom=None, tolerance=0.05, spheroid=False, *
u, unit_name, s = get_srid_info(self.query.transformed_srid, connection)
geodetic = unit_name.lower() in geo_field.geodetic_units
- if backend.spatialite and geodetic:
- raise ValueError('SQLite does not support linear distance calculations on geodetic coordinate systems.')
+ if geodetic and not connection.features.supports_distance_geodetic:
+ raise ValueError('This database does not support linear distance calculations on geodetic coordinate systems.')
if distance:
if self.query.transformed_srid:
@@ -690,8 +690,8 @@ def _distance_attribute(self, func, geom=None, tolerance=0.05, spheroid=False, *
# works on 3D geometries.
procedure_fmt += ",'%(spheroid)s'"
procedure_args.update({'function': backend.length_spheroid, 'spheroid': params[1]})
- elif geom_3d and backend.postgis:
- # Use 3D variants of perimeter and length routines on PostGIS.
+ elif geom_3d and connection.features.supports_3d_functions:
+ # Use 3D variants of perimeter and length routines on supported backends.
if perimeter:
procedure_args.update({'function': backend.perimeter3d})
elif length:
View
3  django/contrib/gis/tests/distapp/models.py
@@ -1,4 +1,5 @@
from django.contrib.gis.db import models
+from django.contrib.gis.tests.utils import gisfield_may_be_null
from django.utils.encoding import python_2_unicode_compatible
@@ -38,7 +39,7 @@ class CensusZipcode(NamedModel):
class SouthTexasZipcode(NamedModel):
"Model for a few South Texas ZIP codes."
- poly = models.PolygonField(srid=32140, null=True)
+ poly = models.PolygonField(srid=32140, null=gisfield_may_be_null)
class Interstate(NamedModel):
View
74 django/contrib/gis/tests/distapp/tests.py
@@ -6,9 +6,7 @@
from django.db.models import Q
from django.contrib.gis.geos import HAS_GEOS
from django.contrib.gis.measure import D # alias for Distance
-from django.contrib.gis.tests.utils import (
- mysql, oracle, postgis, spatialite, no_oracle
-)
+from django.contrib.gis.tests.utils import oracle, postgis, spatialite, no_oracle
from django.test import TestCase, skipUnlessDBFeature
if HAS_GEOS:
@@ -18,8 +16,6 @@
SouthTexasCity, SouthTexasCityFt, CensusZipcode, SouthTexasZipcode)
-@skipUnless(HAS_GEOS and not mysql,
- "GEOS and spatial db (not mysql) are required.")
@skipUnlessDBFeature("gis_enabled")
class DistanceTest(TestCase):
fixtures = ['initial']
@@ -50,7 +46,7 @@ def test_init(self):
self.assertEqual(1, Interstate.objects.count())
self.assertEqual(1, SouthTexasInterstate.objects.count())
- @skipUnlessDBFeature("has_dwithin_lookup")
+ @skipUnlessDBFeature("supports_dwithin_lookup")
def test_dwithin(self):
"""
Test the `dwithin` lookup type.
@@ -99,6 +95,7 @@ def test_dwithin(self):
else:
self.assertListEqual(au_cities, self.get_names(qs.filter(point__dwithin=(self.au_pnt, dist))))
+ @skipUnlessDBFeature("has_distance_method")
def test_distance_projected(self):
"""
Test the `distance` GeoQuerySet method on projected coordinate systems.
@@ -139,7 +136,7 @@ def test_distance_projected(self):
self.assertAlmostEqual(m_distances[i], c.distance.m, tol)
self.assertAlmostEqual(ft_distances[i], c.distance.survey_ft, tol)
- @skipUnlessDBFeature("supports_distance_geodetic")
+ @skipUnlessDBFeature("has_distance_method", "supports_distance_geodetic")
def test_distance_geodetic(self):
"""
Test the `distance` GeoQuerySet method on geodetic coordinate systems.
@@ -149,16 +146,16 @@ def test_distance_geodetic(self):
# Testing geodetic distance calculation with a non-point geometry
# (a LineString of Wollongong and Shellharbour coords).
ls = LineString(((150.902, -34.4245), (150.87, -34.5789)))
- if oracle or postgis:
- # Reference query:
- # SELECT ST_distance_sphere(point, ST_GeomFromText('LINESTRING(150.9020 -34.4245,150.8700 -34.5789)', 4326)) FROM distapp_australiacity ORDER BY name;
- distances = [1120954.92533513, 140575.720018241, 640396.662906304,
- 60580.9693849269, 972807.955955075, 568451.8357838,
- 40435.4335201384, 0, 68272.3896586844, 12375.0643697706, 0]
- qs = AustraliaCity.objects.distance(ls).order_by('name')
- for city, distance in zip(qs, distances):
- # Testing equivalence to within a meter.
- self.assertAlmostEqual(distance, city.distance.m, 0)
+
+ # Reference query:
+ # SELECT ST_distance_sphere(point, ST_GeomFromText('LINESTRING(150.9020 -34.4245,150.8700 -34.5789)', 4326)) FROM distapp_australiacity ORDER BY name;
+ distances = [1120954.92533513, 140575.720018241, 640396.662906304,
+ 60580.9693849269, 972807.955955075, 568451.8357838,
+ 40435.4335201384, 0, 68272.3896586844, 12375.0643697706, 0]
+ qs = AustraliaCity.objects.distance(ls).order_by('name')
+ for city, distance in zip(qs, distances):
+ # Testing equivalence to within a meter.
+ self.assertAlmostEqual(distance, city.distance.m, 0)
# Got the reference distances using the raw SQL statements:
# SELECT ST_distance_spheroid(point, ST_GeomFromText('POINT(151.231341 -33.952685)', 4326), 'SPHEROID["WGS 84",6378137.0,298.257223563]') FROM distapp_australiacity WHERE (NOT (id = 11));
@@ -197,6 +194,7 @@ def test_distance_geodetic(self):
self.assertAlmostEqual(sphere_distances[i], c.distance.m, tol)
@no_oracle # Oracle already handles geographic distance calculation.
+ @skipUnlessDBFeature("has_distance_method")
def test_distance_transform(self):
"""
Test the `distance` GeoQuerySet method used with `transform` on a geographic field.
@@ -226,6 +224,7 @@ def test_distance_transform(self):
for i, z in enumerate(qs):
self.assertAlmostEqual(z.distance.m, dists_m[i], 5)
+ @skipUnlessDBFeature("supports_distances_lookups")
def test_distance_lookups(self):
"""
Test the `distance_lt`, `distance_gt`, `distance_lte`, and `distance_gte` lookup types.
@@ -255,6 +254,7 @@ def test_distance_lookups(self):
qs = SouthTexasZipcode.objects.exclude(name='77005').filter(poly__distance_lte=(z.poly, D(m=300)))
self.assertEqual(['77002', '77025', '77401'], self.get_names(qs))
+ @skipUnlessDBFeature("supports_distances_lookups", "supports_distance_geodetic")
def test_geodetic_distance_lookups(self):
"""
Test distance lookups on geodetic coordinate systems.
@@ -264,23 +264,11 @@ def test_geodetic_distance_lookups(self):
line = GEOSGeometry('LINESTRING(144.9630 -37.8143,151.2607 -33.8870)', 4326)
dist_qs = AustraliaCity.objects.filter(point__distance_lte=(line, D(km=100)))
- if oracle or postgis:
- # Oracle and PostGIS can do distance lookups on arbitrary geometries.
- self.assertEqual(9, dist_qs.count())
- self.assertEqual(['Batemans Bay', 'Canberra', 'Hillsdale',
- 'Melbourne', 'Mittagong', 'Shellharbour',
- 'Sydney', 'Thirroul', 'Wollongong'],
- self.get_names(dist_qs))
- else:
- # spatialite only allow geodetic distance queries (utilizing
- # ST_Distance_Sphere/ST_Distance_Spheroid) from Points to PointFields
- # on geometry columns.
- self.assertRaises(ValueError, dist_qs.count)
-
- # Ensured that a ValueError was raised, none of the rest of the test is
- # support on this backend, so bail now.
- if spatialite:
- return
+ self.assertEqual(9, dist_qs.count())
+ self.assertEqual(['Batemans Bay', 'Canberra', 'Hillsdale',
+ 'Melbourne', 'Mittagong', 'Shellharbour',
+ 'Sydney', 'Thirroul', 'Wollongong'],
+ self.get_names(dist_qs))
# Too many params (4 in this case) should raise a ValueError.
self.assertRaises(ValueError, len,
@@ -309,18 +297,18 @@ def test_geodetic_distance_lookups(self):
# Geodetic distance lookup but telling GeoDjango to use `distance_spheroid`
# instead (we should get the same results b/c accuracy variance won't matter
# in this test case).
- if postgis:
+ querysets = [qs1]
+ if connection.features.has_distance_spheroid_method:
gq3 = Q(point__distance_lte=(wollongong.point, d1, 'spheroid'))
gq4 = Q(point__distance_gte=(wollongong.point, d2, 'spheroid'))
qs2 = AustraliaCity.objects.exclude(name='Wollongong').filter(gq3 | gq4)
- querysets = [qs1, qs2]
- else:
- querysets = [qs1]
+ querysets.append(qs2)
for qs in querysets:
cities = self.get_names(qs)
self.assertEqual(cities, ['Adelaide', 'Hobart', 'Shellharbour', 'Thirroul'])
+ @skipUnlessDBFeature("has_area_method")
def test_area(self):
"""
Test the `area` GeoQuerySet method.
@@ -333,6 +321,7 @@ def test_area(self):
for i, z in enumerate(SouthTexasZipcode.objects.order_by('name').area()):
self.assertAlmostEqual(area_sq_m[i], z.area.sq_m, tol)
+ @skipUnlessDBFeature("has_length_method")
def test_length(self):
"""
Test the `length` GeoQuerySet method.
@@ -342,13 +331,13 @@ def test_length(self):
len_m1 = 473504.769553813
len_m2 = 4617.668
- if spatialite:
- # Does not support geodetic coordinate systems.
- self.assertRaises(ValueError, Interstate.objects.length)
- else:
+ if connection.features.supports_distance_geodetic:
qs = Interstate.objects.length()
tol = 2 if oracle else 3
self.assertAlmostEqual(len_m1, qs[0].length.m, tol)
+ else:
+ # Does not support geodetic coordinate systems.
+ self.assertRaises(ValueError, Interstate.objects.length)
# Now doing length on a projected coordinate system.
i10 = SouthTexasInterstate.objects.length().get(name='I-10')
@@ -370,6 +359,7 @@ def test_perimeter(self):
for i, c in enumerate(SouthTexasCity.objects.perimeter(model_att='perim')):
self.assertEqual(0, c.perim.m)
+ @skipUnlessDBFeature("has_area_method", "has_distance_method")
def test_measurement_null_fields(self):
"""
Test the measurement GeoQuerySet methods on fields with NULL values.
View
8 django/contrib/gis/tests/geo3d/tests.py
@@ -6,8 +6,7 @@
from django.contrib.gis.gdal import HAS_GDAL
from django.contrib.gis.geos import HAS_GEOS
-from django.contrib.gis.tests.utils import postgis
-from django.test import TestCase
+from django.test import TestCase, skipUnlessDBFeature
from django.utils._os import upath
if HAS_GEOS:
@@ -62,7 +61,8 @@
)
-@skipUnless(HAS_GEOS and HAS_GDAL and postgis, "Geos, GDAL and postgis are required.")
+@skipUnless(HAS_GDAL, "GDAL is required for Geo3DTest.")
+@skipUnlessDBFeature("gis_enabled", "supports_3d_functions")
class Geo3DTest(TestCase):
"""
Only a subset of the PostGIS routines are 3D-enabled, and this TestCase
@@ -70,7 +70,7 @@ class Geo3DTest(TestCase):
available within GeoDjango. For more information, see the PostGIS docs
on the routines that support 3D:
- http://postgis.refractions.net/documentation/manual-1.5/ch08.html#PostGIS_3D_Functions
+ http://postgis.net/docs/PostGIS_Special_Functions_Index.html#PostGIS_3D_Functions
"""
def _load_interstate_data(self):
View
7 django/contrib/gis/tests/geoapp/models.py
@@ -1,10 +1,7 @@
from django.contrib.gis.db import models
-from django.contrib.gis.tests.utils import mysql
+from django.contrib.gis.tests.utils import gisfield_may_be_null
from django.utils.encoding import python_2_unicode_compatible
-# MySQL spatial indices can't handle NULL geometries.
-null_flag = not mysql
-
@python_2_unicode_compatible
class NamedModel(models.Model):
@@ -42,7 +39,7 @@ class Meta:
class State(NamedModel):
- poly = models.PolygonField(null=null_flag) # Allowing NULL geometries here.
+ poly = models.PolygonField(null=gisfield_may_be_null) # Allowing NULL geometries here.
class Track(NamedModel):
View
36 django/contrib/gis/tests/geoapp/tests.py
@@ -2,12 +2,11 @@
import re
import unittest
-from unittest import skipUnless
from django.db import connection
from django.contrib.gis import gdal
from django.contrib.gis.geos import HAS_GEOS
-from django.contrib.gis.tests.utils import mysql, oracle, postgis, spatialite
+from django.contrib.gis.tests.utils import oracle, postgis, spatialite
from django.test import TestCase, skipUnlessDBFeature
from django.utils import six
@@ -142,11 +141,12 @@ def test_lookup_insert_transform(self):
# If the GeometryField SRID is -1, then we shouldn't perform any
# transformation if the SRID of the input geometry is different.
- # SpatiaLite does not support missing SRID values.
- if not spatialite:
- m1 = MinusOneSRID(geom=Point(17, 23, srid=4326))
- m1.save()
- self.assertEqual(-1, m1.geom.srid)
+ if spatialite and connection.ops.spatial_version < 3:
+ # SpatiaLite < 3 does not support missing SRID values.
+ return
+ m1 = MinusOneSRID(geom=Point(17, 23, srid=4326))
+ m1.save()
+ self.assertEqual(-1, m1.geom.srid)
def test_createnull(self):
"Testing creating a model instance and the geometry being None"
@@ -223,7 +223,7 @@ def test_contains_contained_lookups(self):
# Seeing what cities are in Texas, should get Houston and Dallas,
# and Oklahoma City because 'contained' only checks on the
# _bounding box_ of the Geometries.
- if not oracle:
+ if connection.features.supports_contained_lookup:
qs = City.objects.filter(point__contained=texas.mpoly)
self.assertEqual(3, qs.count())
cities = ['Houston', 'Dallas', 'Oklahoma City']
@@ -245,23 +245,22 @@ def test_contains_contained_lookups(self):
self.assertEqual('New Zealand', nz.name)
# Spatialite 2.3 thinks that Lawrence is in Puerto Rico (a NULL geometry).
- if not spatialite:
+ if not (spatialite and connection.ops.spatial_version < 3):
ks = State.objects.get(poly__contains=lawrence.point)
self.assertEqual('Kansas', ks.name)
# Pueblo and Oklahoma City (even though OK City is within the bounding box of Texas)
# are not contained in Texas or New Zealand.
- self.assertEqual(0, len(Country.objects.filter(mpoly__contains=pueblo.point))) # Query w/GEOSGeometry object
- self.assertEqual((mysql and 1) or 0,
- len(Country.objects.filter(mpoly__contains=okcity.point.wkt))) # Qeury w/WKT
+ self.assertEqual(len(Country.objects.filter(mpoly__contains=pueblo.point)), 0) # Query w/GEOSGeometry object
+ self.assertEqual(len(Country.objects.filter(mpoly__contains=okcity.point.wkt)),
+ 0 if connection.features.supports_real_shape_operations else 1) # Query w/WKT
# OK City is contained w/in bounding box of Texas.
- if not oracle:
+ if connection.features.supports_bbcontains_lookup:
qs = Country.objects.filter(mpoly__bbcontains=okcity.point)
self.assertEqual(1, len(qs))
self.assertEqual('Texas', qs[0].name)
- # Only PostGIS has `left` and `right` lookup types.
@skipUnlessDBFeature("supports_left_right_lookups")
def test_left_right_lookups(self):
"Testing the 'left' and 'right' lookup types."
@@ -409,10 +408,9 @@ def test_centroid(self):
for s in qs:
self.assertEqual(True, s.poly.centroid.equals_exact(s.centroid, tol))
- @skipUnlessDBFeature("has_difference_method")
- @skipUnlessDBFeature("has_intersection_method")
- @skipUnlessDBFeature("has_sym_difference_method")
- @skipUnlessDBFeature("has_union_method")
+ @skipUnlessDBFeature(
+ "has_difference_method", "has_intersection_method",
+ "has_sym_difference_method", "has_union_method")
def test_diff_intersection_union(self):
"Testing the `difference`, `intersection`, `sym_difference`, and `union` GeoQuerySet methods."
geom = Point(5, 23)
@@ -610,7 +608,7 @@ def test_point_on_surface(self):
'Texas': fromstr('POINT (-103.002434 36.500397)', srid=4326),
}
- elif postgis or spatialite:
+ else:
# Using GEOSGeometry to compute the reference point on surface values
# -- since PostGIS also uses GEOS these should be the same.
ref = {'New Zealand': Country.objects.get(name='New Zealand').mpoly.point_on_surface,
View
8 django/contrib/gis/tests/geogapp/tests.py
@@ -10,14 +10,14 @@
from django.contrib.gis.geos import HAS_GEOS
from django.contrib.gis.measure import D
from django.contrib.gis.tests.utils import postgis
-from django.test import TestCase
+from django.test import TestCase, skipUnlessDBFeature
from django.utils._os import upath
if HAS_GEOS:
from .models import City, County, Zipcode
-@skipUnless(HAS_GEOS and postgis, "Geos and postgis are required.")
+@skipUnlessDBFeature("gis_enabled")
class GeographyTest(TestCase):
fixtures = ['initial']
@@ -25,6 +25,7 @@ def test01_fixture_load(self):
"Ensure geography features loaded properly."
self.assertEqual(8, City.objects.count())
+ @skipUnlessDBFeature("supports_distances_lookups", "supports_distance_geodetic")
def test02_distance_lookup(self):
"Testing GeoQuerySet distance lookup support on non-point geography fields."
z = Zipcode.objects.get(code='77002')
@@ -39,12 +40,14 @@ def test02_distance_lookup(self):
for cities in [cities1, cities2]:
self.assertEqual(['Dallas', 'Houston', 'Oklahoma City'], cities)
+ @skipUnlessDBFeature("has_distance_method", "supports_distance_geodetic")
def test03_distance_method(self):
"Testing GeoQuerySet.distance() support on non-point geography fields."
# `GeoQuerySet.distance` is not allowed geometry fields.
htown = City.objects.get(name='Houston')
Zipcode.objects.distance(htown.point)
+ @skipUnless(postgis, "This is a PostGIS-specific test")
def test04_invalid_operators_functions(self):
"Ensuring exceptions are raised for operators & functions invalid on geography fields."
# Only a subset of the geometry functions & operator are available
@@ -89,6 +92,7 @@ def test05_geography_layermapping(self):
self.assertEqual(name, c.name)
self.assertEqual(state, c.state)
+ @skipUnlessDBFeature("has_area_method", "supports_distance_geodetic")
def test06_geography_area(self):
"Testing that Area calculations work on geography columns."
# SELECT ST_Area(poly) FROM geogapp_zipcode WHERE code='77002';
View
33 django/contrib/gis/tests/inspectapp/tests.py
@@ -1,6 +1,7 @@
from __future__ import unicode_literals
import os
+import re
from unittest import skipUnless
from django.core.management import call_command
@@ -11,7 +12,7 @@
from django.utils.six import StringIO
if HAS_GDAL:
- from django.contrib.gis.gdal import Driver
+ from django.contrib.gis.gdal import Driver, OGRException
from django.contrib.gis.utils.ogrinspect import ogrinspect
from .models import AllOGRFields
@@ -77,23 +78,20 @@ def test_date_field(self):
self.assertEqual(model_def, '\n'.join(expected))
def test_time_field(self):
- # Only possible to test this on PostGIS at the moment. MySQL
- # complains about permissions, and SpatiaLite/Oracle are
- # insanely difficult to get support compiled in for in GDAL.
- if not connections['default'].ops.postgis:
- self.skipTest("This database does not support 'ogrinspect'ion")
-
# Getting the database identifier used by OGR, if None returned
# GDAL does not have the support compiled in.
ogr_db = get_ogr_db_string()
if not ogr_db:
- self.skipTest("Your GDAL installation does not support PostGIS databases")
+ self.skipTest("Unable to setup an OGR connection to your database")
- # Writing shapefiles via GDAL currently does not support writing OGRTime
- # fields, so we need to actually use a database
- model_def = ogrinspect(ogr_db, 'Measurement',
- layer_key=AllOGRFields._meta.db_table,
- decimal=['f_decimal'])
+ try:
+ # Writing shapefiles via GDAL currently does not support writing OGRTime
+ # fields, so we need to actually use a database
+ model_def = ogrinspect(ogr_db, 'Measurement',
+ layer_key=AllOGRFields._meta.db_table,
+ decimal=['f_decimal'])
+ except OGRException:
+ self.skipTest("Unable to setup an OGR connection to your database")
self.assertTrue(model_def.startswith(
'# This is an auto-generated Django model module created by ogrinspect.\n'
@@ -111,10 +109,9 @@ def test_time_field(self):
self.assertIn(' f_char = models.CharField(max_length=10)', model_def)
self.assertIn(' f_date = models.DateField()', model_def)
- self.assertTrue(model_def.endswith(
- ' geom = models.PolygonField()\n'
- ' objects = models.GeoManager()'
- ))
+ self.assertIsNotNone(re.search(
+ r' geom = models.PolygonField\(([^\)])*\)\n' # Some backends may have srid=-1
+ r' objects = models.GeoManager\(\)', model_def))
def test_management_command(self):
shp_file = os.path.join(TEST_DATA, 'cities', 'cities.shp')
@@ -142,7 +139,7 @@ def get_ogr_db_string():
'django.contrib.gis.db.backends.spatialite': ('SQLite', '%(db_name)s', '')
}
- drv_name, db_str, param_sep = drivers[db['ENGINE']]
+ drv_name, db_str, param_sep = drivers.get(db['ENGINE'])
# Ensure that GDAL library has driver support for the database.
try:
View
7 django/contrib/gis/tests/layermap/tests.py
@@ -8,8 +8,7 @@
from unittest import skipUnless
from django.contrib.gis.gdal import HAS_GDAL
-from django.contrib.gis.tests.utils import mysql
-from django.db import router
+from django.db import connection, router
from django.conf import settings
from django.test import TestCase, skipUnlessDBFeature
from django.utils._os import upath
@@ -151,7 +150,7 @@ def test_layermap_unique_multigeometry_fk(self):
# Unique may take tuple or string parameters.
for arg in ('name', ('name', 'mpoly')):
lm = LayerMapping(County, co_shp, co_mapping, transform=False, unique=arg)
- except:
+ except Exception:
self.fail('No exception should be raised for proper use of keywords.')
# Testing invalid params for the `unique` keyword.
@@ -159,7 +158,7 @@ def test_layermap_unique_multigeometry_fk(self):
self.assertRaises(e, LayerMapping, County, co_shp, co_mapping, transform=False, unique=arg)
# No source reference system defined in the shapefile, should raise an error.
- if not mysql:
+ if connection.features.supports_transform:
self.assertRaises(LayerMapError, LayerMapping, County, co_shp, co_mapping)
# Passing in invalid ForeignKey mapping parameters -- must be a dictionary
View
7 django/contrib/gis/tests/relatedapp/tests.py
@@ -1,7 +1,8 @@
from __future__ import unicode_literals
from django.contrib.gis.geos import HAS_GEOS
-from django.contrib.gis.tests.utils import mysql, no_oracle
+from django.contrib.gis.tests.utils import no_oracle
+from django.db import connection
from django.test import TestCase, skipUnlessDBFeature
if HAS_GEOS:
@@ -146,7 +147,7 @@ def test06_f_expressions(self):
self.assertEqual(1, len(qs))
self.assertEqual('P2', qs[0].name)
- if not mysql:
+ if connection.features.supports_transform:
# This time center2 is in a different coordinate system and needs
# to be wrapped in transformation SQL.
qs = Parcel.objects.filter(center2__within=F('border1'))
@@ -159,7 +160,7 @@ def test06_f_expressions(self):
self.assertEqual(1, len(qs))
self.assertEqual('P1', qs[0].name)
- if not mysql:
+ if connection.features.supports_transform:
# This time the city column should be wrapped in transformation SQL.
qs = Parcel.objects.filter(border2__contains=F('city__location__point'))
self.assertEqual(1, len(qs))
View
3  django/contrib/gis/tests/utils.py
@@ -28,6 +28,9 @@ def no_oracle(func):
mysql = _default_db == 'mysql'
spatialite = _default_db == 'spatialite'
+# MySQL spatial indices can't handle NULL geometries.
+gisfield_may_be_null = not mysql
+
if oracle and 'gis' in settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE']:
from django.contrib.gis.db.backends.oracle.models import OracleSpatialRefSys as SpatialRefSys
elif postgis:
View
6 django/contrib/gis/utils/layermapping.py
@@ -103,10 +103,10 @@ def __init__(self, model, data, mapping, layer=0,
# Getting the geometry column associated with the model (an
# exception will be raised if there is no geometry column).
- if self.spatial_backend.mysql:
- transform = False
- else:
+ if connections[self.using].features.supports_transform:
self.geo_field = self.geometry_field()
+ else:
+ transform = False
# Checking the source spatial reference system, and getting
# the coordinate transformation object (unless the `transform`
Please sign in to comment.
Something went wrong with that request. Please try again.