diff --git a/django/contrib/gis/db/backends/base/features.py b/django/contrib/gis/db/backends/base/features.py index ff16701795..e714440e58 100644 --- a/django/contrib/gis/db/backends/base/features.py +++ b/django/contrib/gis/db/backends/base/features.py @@ -14,6 +14,8 @@ class BaseSpatialFeatures: # Does the backend introspect GeometryField to its subtypes? supports_geometry_field_introspection = True + # Does the database have a geography type? + supports_geography = False # Does the backend support storing 3D geometries? supports_3d_storage = False # Reference implementation of 3D functions is: diff --git a/django/contrib/gis/db/backends/base/operations.py b/django/contrib/gis/db/backends/base/operations.py index b0331f051a..2956fa3c9a 100644 --- a/django/contrib/gis/db/backends/base/operations.py +++ b/django/contrib/gis/db/backends/base/operations.py @@ -23,9 +23,6 @@ class BaseSpatialOperations: def select_extent(self): return self.select - # Does the spatial database have a geography type? - geography = False - # Aggregates disallowed_aggregates = () diff --git a/django/contrib/gis/db/backends/postgis/features.py b/django/contrib/gis/db/backends/postgis/features.py index 60158ca5c3..1607f29bbf 100644 --- a/django/contrib/gis/db/backends/postgis/features.py +++ b/django/contrib/gis/db/backends/postgis/features.py @@ -5,6 +5,7 @@ from django.db.backends.postgresql.features import ( class DatabaseFeatures(BaseSpatialFeatures, Psycopg2DatabaseFeatures): + supports_geography = True supports_3d_storage = True supports_3d_functions = True supports_left_right_lookups = True diff --git a/django/contrib/gis/db/backends/postgis/operations.py b/django/contrib/gis/db/backends/postgis/operations.py index e9bcfc8a30..f068f28f48 100644 --- a/django/contrib/gis/db/backends/postgis/operations.py +++ b/django/contrib/gis/db/backends/postgis/operations.py @@ -98,7 +98,6 @@ class ST_Polygon(Func): class PostGISOperations(BaseSpatialOperations, DatabaseOperations): name = 'postgis' postgis = True - geography = True geom_func_prefix = 'ST_' Adapter = PostGISAdapter diff --git a/django/contrib/gis/db/models/fields.py b/django/contrib/gis/db/models/fields.py index af5abb549e..16b3bb5d08 100644 --- a/django/contrib/gis/db/models/fields.py +++ b/django/contrib/gis/db/models/fields.py @@ -145,7 +145,11 @@ class BaseSpatialField(Field): return None return connection.ops.Adapter( super().get_db_prep_value(value, connection, *args, **kwargs), - **({'geography': True} if self.geography and connection.ops.geography else {}) + **( + {'geography': True} + if self.geography and connection.features.supports_geography + else {} + ) ) def get_raster_prep_value(self, value, is_candidate): diff --git a/tests/gis_tests/geogapp/tests.py b/tests/gis_tests/geogapp/tests.py index 9cf8ab92f7..507d8a970e 100644 --- a/tests/gis_tests/geogapp/tests.py +++ b/tests/gis_tests/geogapp/tests.py @@ -95,7 +95,7 @@ class GeographyFunctionTests(FuncTestMixin, TestCase): Cast a geography to a geometry field for an aggregate function that expects a geometry input. """ - if not connection.ops.geography: + if not connection.features.supports_geography: self.skipTest("This test needs geography support") expected = (-96.8016128540039, 29.7633724212646, -95.3631439208984, 32.782058715820) res = City.objects.filter( diff --git a/tests/gis_tests/inspectapp/tests.py b/tests/gis_tests/inspectapp/tests.py index 5fac4d9884..61e7d3543a 100644 --- a/tests/gis_tests/inspectapp/tests.py +++ b/tests/gis_tests/inspectapp/tests.py @@ -10,7 +10,7 @@ from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature from django.test.utils import modify_settings from ..test_data import TEST_DATA -from ..utils import mariadb, postgis +from ..utils import mariadb from .models import AllOGRFields @@ -44,9 +44,10 @@ class InspectDbTests(TestCase): output = out.getvalue() if connection.features.supports_geometry_field_introspection: self.assertIn('point = models.PointField(dim=3)', output) - if postgis: - # Geography type is specific to PostGIS + if connection.features.supports_geography: self.assertIn('pointg = models.PointField(geography=True, dim=3)', output) + else: + self.assertIn('pointg = models.PointField(dim=3)', output) self.assertIn('line = models.LineStringField(dim=3)', output) self.assertIn('poly = models.PolygonField(dim=3)', output) else: