mirror of https://github.com/django/django.git
Deprecated legacy GeoManager/GeoQuerySet methods
This commit is contained in:
parent
71e20814fc
commit
ea27e26b09
|
@ -1,5 +1,8 @@
|
|||
import warnings
|
||||
|
||||
from django.contrib.gis.db.models.query import GeoQuerySet
|
||||
from django.db.models.manager import Manager
|
||||
from django.utils.deprecation import RemovedInDjango21Warning
|
||||
|
||||
|
||||
class GeoManager(Manager.from_queryset(GeoQuerySet)):
|
||||
|
@ -9,3 +12,11 @@ class GeoManager(Manager.from_queryset(GeoQuerySet)):
|
|||
# so that geometry columns on Oracle and MySQL are selected
|
||||
# properly.
|
||||
use_for_related_fields = True
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
warnings.warn(
|
||||
"The GeoManager class is deprecated. Simply use a normal manager "
|
||||
"once you have replaced all calls to GeoQuerySet methods by annotations.",
|
||||
RemovedInDjango21Warning, stacklevel=2
|
||||
)
|
||||
super(GeoManager, self).__init__(*args, **kwargs)
|
||||
|
|
|
@ -15,7 +15,9 @@ from django.db.models.expressions import RawSQL
|
|||
from django.db.models.fields import Field
|
||||
from django.db.models.query import QuerySet
|
||||
from django.utils import six
|
||||
from django.utils.deprecation import RemovedInDjango20Warning
|
||||
from django.utils.deprecation import (
|
||||
RemovedInDjango20Warning, RemovedInDjango21Warning,
|
||||
)
|
||||
|
||||
|
||||
class GeoQuerySet(QuerySet):
|
||||
|
@ -513,6 +515,11 @@ class GeoQuerySet(QuerySet):
|
|||
The name of the model attribute to attach the output of
|
||||
the spatial function to.
|
||||
"""
|
||||
warnings.warn(
|
||||
"The %s GeoQuerySet method is deprecated. See GeoDjango Functions "
|
||||
"documentation to find the expression-based replacement." % att,
|
||||
RemovedInDjango21Warning, stacklevel=2
|
||||
)
|
||||
# Default settings.
|
||||
settings.setdefault('desc', None)
|
||||
settings.setdefault('geom_args', ())
|
||||
|
|
|
@ -2,6 +2,7 @@ from __future__ import unicode_literals
|
|||
|
||||
from django.apps import apps
|
||||
from django.contrib.gis.db.models.fields import GeometryField
|
||||
from django.contrib.gis.db.models.functions import AsKML, Transform
|
||||
from django.contrib.gis.shortcuts import render_to_kml, render_to_kmz
|
||||
from django.core.exceptions import FieldDoesNotExist
|
||||
from django.db import DEFAULT_DB_ALIAS, connections
|
||||
|
@ -31,15 +32,17 @@ def kml(request, label, model, field_name=None, compress=False, using=DEFAULT_DB
|
|||
|
||||
connection = connections[using]
|
||||
|
||||
if connection.features.has_kml_method:
|
||||
if connection.features.has_AsKML_function:
|
||||
# Database will take care of transformation.
|
||||
placemarks = klass._default_manager.using(using).kml(field_name=field_name)
|
||||
placemarks = klass._default_manager.using(using).annotate(kml=AsKML(field_name))
|
||||
else:
|
||||
# If the database offers no KML method, we use the `kml`
|
||||
# attribute of the lazy geometry instead.
|
||||
placemarks = []
|
||||
if connection.features.has_transform_method:
|
||||
qs = klass._default_manager.using(using).transform(4326, field_name=field_name)
|
||||
if connection.features.has_Transform_function:
|
||||
qs = klass._default_manager.using(using).annotate(
|
||||
**{'%s_4326' % field_name: Transform(field_name, 4326)})
|
||||
field_name += '_4326'
|
||||
else:
|
||||
qs = klass._default_manager.using(using).all()
|
||||
for mod in qs:
|
||||
|
|
|
@ -35,6 +35,8 @@ details on these changes.
|
|||
* The ``django.contrib.auth.tests.utils.skipIfCustomUser()`` decorator will be
|
||||
removed.
|
||||
|
||||
* The ``GeoManager`` and ``GeoQuerySet`` classes will be removed.
|
||||
|
||||
.. _deprecation-removed-in-2.0:
|
||||
|
||||
2.0
|
||||
|
|
|
@ -400,6 +400,16 @@ of its methods and attributes are either changed or renamed.
|
|||
|
||||
The aim of these changes is to provide a documented API for relation fields.
|
||||
|
||||
``GeoManager`` and ``GeoQuerySet`` custom methods
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
All custom ``GeoQuerySet`` methods (``area()``, ``distance()``, ``gml()``, ...)
|
||||
have been replaced by equivalent geographic expressions in annotations (see in
|
||||
new features). Hence the need to set a custom ``GeoManager`` to GIS-enabled
|
||||
models is now obsolete. As soon as your code doesn't call any of the deprecated
|
||||
methods, you can simply remove the ``objects = GeoManager()`` lines from your
|
||||
models.
|
||||
|
||||
Miscellaneous
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ from django.contrib.gis.geos import HAS_GEOS
|
|||
from django.contrib.gis.measure import D # alias for Distance
|
||||
from django.db import connection
|
||||
from django.db.models import Q
|
||||
from django.test import TestCase, skipUnlessDBFeature
|
||||
from django.test import TestCase, ignore_warnings, skipUnlessDBFeature
|
||||
from django.utils.deprecation import RemovedInDjango21Warning
|
||||
|
||||
from ..utils import no_oracle, oracle, postgis, spatialite
|
||||
|
||||
|
@ -98,6 +99,7 @@ class DistanceTest(TestCase):
|
|||
self.assertListEqual(au_cities, self.get_names(qs.filter(point__dwithin=(self.au_pnt, dist))))
|
||||
|
||||
@skipUnlessDBFeature("has_distance_method")
|
||||
@ignore_warnings(category=RemovedInDjango21Warning)
|
||||
def test_distance_projected(self):
|
||||
"""
|
||||
Test the `distance` GeoQuerySet method on projected coordinate systems.
|
||||
|
@ -141,6 +143,7 @@ class DistanceTest(TestCase):
|
|||
self.assertAlmostEqual(ft_distances[i], c.distance.survey_ft, tol)
|
||||
|
||||
@skipUnlessDBFeature("has_distance_method", "supports_distance_geodetic")
|
||||
@ignore_warnings(category=RemovedInDjango21Warning)
|
||||
def test_distance_geodetic(self):
|
||||
"""
|
||||
Test the `distance` GeoQuerySet method on geodetic coordinate systems.
|
||||
|
@ -202,6 +205,7 @@ class DistanceTest(TestCase):
|
|||
|
||||
@no_oracle # Oracle already handles geographic distance calculation.
|
||||
@skipUnlessDBFeature("has_distance_method")
|
||||
@ignore_warnings(category=RemovedInDjango21Warning)
|
||||
def test_distance_transform(self):
|
||||
"""
|
||||
Test the `distance` GeoQuerySet method used with `transform` on a geographic field.
|
||||
|
@ -322,6 +326,7 @@ class DistanceTest(TestCase):
|
|||
self.assertEqual(cities, ['Adelaide', 'Hobart', 'Shellharbour', 'Thirroul'])
|
||||
|
||||
@skipUnlessDBFeature("has_area_method")
|
||||
@ignore_warnings(category=RemovedInDjango21Warning)
|
||||
def test_area(self):
|
||||
"""
|
||||
Test the `area` GeoQuerySet method.
|
||||
|
@ -335,6 +340,7 @@ class DistanceTest(TestCase):
|
|||
self.assertAlmostEqual(area_sq_m[i], z.area.sq_m, tol)
|
||||
|
||||
@skipUnlessDBFeature("has_length_method")
|
||||
@ignore_warnings(category=RemovedInDjango21Warning)
|
||||
def test_length(self):
|
||||
"""
|
||||
Test the `length` GeoQuerySet method.
|
||||
|
@ -358,6 +364,7 @@ class DistanceTest(TestCase):
|
|||
self.assertAlmostEqual(len_m2, i10.length.m, 2)
|
||||
|
||||
@skipUnlessDBFeature("has_perimeter_method")
|
||||
@ignore_warnings(category=RemovedInDjango21Warning)
|
||||
def test_perimeter(self):
|
||||
"""
|
||||
Test the `perimeter` GeoQuerySet method.
|
||||
|
@ -374,6 +381,7 @@ class DistanceTest(TestCase):
|
|||
self.assertEqual(0, c.perim.m)
|
||||
|
||||
@skipUnlessDBFeature("has_area_method", "has_distance_method")
|
||||
@ignore_warnings(category=RemovedInDjango21Warning)
|
||||
def test_measurement_null_fields(self):
|
||||
"""
|
||||
Test the measurement GeoQuerySet methods on fields with NULL values.
|
||||
|
@ -388,6 +396,7 @@ class DistanceTest(TestCase):
|
|||
self.assertIsNone(z.area)
|
||||
|
||||
@skipUnlessDBFeature("has_distance_method")
|
||||
@ignore_warnings(category=RemovedInDjango21Warning)
|
||||
def test_distance_order_by(self):
|
||||
qs = SouthTexasCity.objects.distance(Point(3, 3)).order_by(
|
||||
'distance'
|
||||
|
|
|
@ -11,7 +11,9 @@ from django.contrib.gis.gdal import HAS_GDAL
|
|||
from django.contrib.gis.geos import HAS_GEOS
|
||||
from django.test import TestCase, ignore_warnings, skipUnlessDBFeature
|
||||
from django.utils._os import upath
|
||||
from django.utils.deprecation import RemovedInDjango20Warning
|
||||
from django.utils.deprecation import (
|
||||
RemovedInDjango20Warning, RemovedInDjango21Warning,
|
||||
)
|
||||
|
||||
if HAS_GEOS:
|
||||
from django.contrib.gis.db.models import Union, Extent3D
|
||||
|
@ -172,6 +174,7 @@ class Geo3DTest(Geo3DLoadingHelper, TestCase):
|
|||
lm.save()
|
||||
self.assertEqual(3, MultiPoint3D.objects.count())
|
||||
|
||||
@ignore_warnings(category=RemovedInDjango21Warning)
|
||||
def test_kml(self):
|
||||
"""
|
||||
Test GeoQuerySet.kml() with Z values.
|
||||
|
@ -183,6 +186,7 @@ class Geo3DTest(Geo3DLoadingHelper, TestCase):
|
|||
ref_kml_regex = re.compile(r'^<Point><coordinates>-95.363\d+,29.763\d+,18</coordinates></Point>$')
|
||||
self.assertTrue(ref_kml_regex.match(h.kml))
|
||||
|
||||
@ignore_warnings(category=RemovedInDjango21Warning)
|
||||
def test_geojson(self):
|
||||
"""
|
||||
Test GeoQuerySet.geojson() with Z values.
|
||||
|
@ -234,6 +238,7 @@ class Geo3DTest(Geo3DLoadingHelper, TestCase):
|
|||
self.assertIsNone(City3D.objects.none().extent3d())
|
||||
self.assertIsNone(City3D.objects.none().aggregate(Extent3D('point'))['point__extent3d'])
|
||||
|
||||
@ignore_warnings(category=RemovedInDjango21Warning)
|
||||
@skipUnlessDBFeature("supports_3d_functions")
|
||||
def test_perimeter(self):
|
||||
"""
|
||||
|
@ -252,6 +257,7 @@ class Geo3DTest(Geo3DLoadingHelper, TestCase):
|
|||
Polygon3D.objects.perimeter().get(name='3D BBox').perimeter.m,
|
||||
tol)
|
||||
|
||||
@ignore_warnings(category=RemovedInDjango21Warning)
|
||||
@skipUnlessDBFeature("supports_3d_functions")
|
||||
def test_length(self):
|
||||
"""
|
||||
|
@ -285,6 +291,7 @@ class Geo3DTest(Geo3DLoadingHelper, TestCase):
|
|||
InterstateProj3D.objects.length().get(name='I-45').length.m,
|
||||
tol)
|
||||
|
||||
@ignore_warnings(category=RemovedInDjango21Warning)
|
||||
@skipUnlessDBFeature("supports_3d_functions")
|
||||
def test_scale(self):
|
||||
"""
|
||||
|
@ -297,6 +304,7 @@ class Geo3DTest(Geo3DLoadingHelper, TestCase):
|
|||
for city in City3D.objects.scale(1.0, 1.0, zscale):
|
||||
self.assertEqual(city_dict[city.name][2] * zscale, city.scale.z)
|
||||
|
||||
@ignore_warnings(category=RemovedInDjango21Warning)
|
||||
@skipUnlessDBFeature("supports_3d_functions")
|
||||
def test_translate(self):
|
||||
"""
|
||||
|
|
|
@ -9,7 +9,9 @@ from django.core.management import call_command
|
|||
from django.db import connection
|
||||
from django.test import TestCase, ignore_warnings, skipUnlessDBFeature
|
||||
from django.utils import six
|
||||
from django.utils.deprecation import RemovedInDjango20Warning
|
||||
from django.utils.deprecation import (
|
||||
RemovedInDjango20Warning, RemovedInDjango21Warning,
|
||||
)
|
||||
|
||||
from ..utils import no_oracle, oracle, postgis, spatialite
|
||||
|
||||
|
@ -431,6 +433,7 @@ class GeoLookupTest(TestCase):
|
|||
|
||||
|
||||
@skipUnlessDBFeature("gis_enabled")
|
||||
@ignore_warnings(category=RemovedInDjango21Warning)
|
||||
class GeoQuerySetTest(TestCase):
|
||||
fixtures = ['initial']
|
||||
|
||||
|
|
|
@ -10,8 +10,9 @@ from django.contrib.gis.db.models.functions import Area, Distance
|
|||
from django.contrib.gis.gdal import HAS_GDAL
|
||||
from django.contrib.gis.geos import HAS_GEOS
|
||||
from django.contrib.gis.measure import D
|
||||
from django.test import TestCase, skipUnlessDBFeature
|
||||
from django.test import TestCase, ignore_warnings, skipUnlessDBFeature
|
||||
from django.utils._os import upath
|
||||
from django.utils.deprecation import RemovedInDjango21Warning
|
||||
|
||||
from ..utils import oracle, postgis
|
||||
|
||||
|
@ -43,6 +44,7 @@ class GeographyTest(TestCase):
|
|||
self.assertEqual(['Dallas', 'Houston', 'Oklahoma City'], cities)
|
||||
|
||||
@skipUnlessDBFeature("has_distance_method", "supports_distance_geodetic")
|
||||
@ignore_warnings(category=RemovedInDjango21Warning)
|
||||
def test03_distance_method(self):
|
||||
"Testing GeoQuerySet.distance() support on non-point geography fields."
|
||||
# `GeoQuerySet.distance` is not allowed geometry fields.
|
||||
|
@ -95,6 +97,7 @@ class GeographyTest(TestCase):
|
|||
self.assertEqual(state, c.state)
|
||||
|
||||
@skipUnlessDBFeature("has_area_method", "supports_distance_geodetic")
|
||||
@ignore_warnings(category=RemovedInDjango21Warning)
|
||||
def test06_geography_area(self):
|
||||
"Testing that Area calculations work on geography columns."
|
||||
# SELECT ST_Area(poly) FROM geogapp_zipcode WHERE code='77002';
|
||||
|
|
|
@ -158,6 +158,11 @@ def setup(verbosity, test_labels):
|
|||
'django.contrib.webdesign will be removed in Django 2.0.',
|
||||
RemovedInDjango20Warning
|
||||
)
|
||||
warnings.filterwarnings(
|
||||
'ignore',
|
||||
'The GeoManager class is deprecated.',
|
||||
RemovedInDjango21Warning
|
||||
)
|
||||
|
||||
# Load all the ALWAYS_INSTALLED_APPS.
|
||||
django.setup()
|
||||
|
|
Loading…
Reference in New Issue