1
0
mirror of https://github.com/django/django.git synced 2024-12-22 09:05:43 +00:00

Refs #27674 -- Removed GeoModelAdmin and OSMGeoAdmin per deprecation timeline.

This commit is contained in:
Mariusz Felisiak 2023-01-10 13:01:14 +01:00
parent 2fad163257
commit 4982958ec0
14 changed files with 4 additions and 608 deletions

View File

@ -11,7 +11,7 @@ from django.contrib.admin import (
register,
site,
)
from django.contrib.gis.admin.options import GeoModelAdmin, GISModelAdmin, OSMGeoAdmin
from django.contrib.gis.admin.options import GISModelAdmin
from django.contrib.gis.admin.widgets import OpenLayersWidget
__all__ = [
@ -28,7 +28,5 @@ __all__ = [
"site",
"GISModelAdmin",
# RemovedInDjango50Warning.
"GeoModelAdmin",
"OpenLayersWidget",
"OSMGeoAdmin",
]

View File

@ -1,12 +1,6 @@
import warnings
from django.contrib.admin import ModelAdmin
from django.contrib.gis.admin.widgets import OpenLayersWidget
from django.contrib.gis.db import models
from django.contrib.gis.forms import OSMWidget
from django.contrib.gis.gdal import OGRGeomType
from django.forms import Media
from django.utils.deprecation import RemovedInDjango50Warning
class GeoModelAdminMixin:
@ -25,156 +19,3 @@ class GeoModelAdminMixin:
class GISModelAdmin(GeoModelAdminMixin, ModelAdmin):
pass
# RemovedInDjango50Warning.
spherical_mercator_srid = 3857
# RemovedInDjango50Warning.
class GeoModelAdmin(ModelAdmin):
"""
The administration options class for Geographic models. Map settings
may be overloaded from their defaults to create custom maps.
"""
# The default map settings that may be overloaded -- still subject
# to API changes.
default_lon = 0
default_lat = 0
default_zoom = 4
display_wkt = False
display_srid = False
extra_js = []
num_zoom = 18
max_zoom = False
min_zoom = False
units = False
max_resolution = False
max_extent = False
modifiable = True
mouse_position = True
scale_text = True
layerswitcher = True
scrollable = True
map_width = 600
map_height = 400
map_srid = 4326
map_template = "gis/admin/openlayers.html"
openlayers_url = (
"https://cdnjs.cloudflare.com/ajax/libs/openlayers/2.13.1/OpenLayers.js"
)
point_zoom = num_zoom - 6
wms_url = "http://vmap0.tiles.osgeo.org/wms/vmap0"
wms_layer = "basic"
wms_name = "OpenLayers WMS"
wms_options = {"format": "image/jpeg"}
debug = False
widget = OpenLayersWidget
def __init__(self, *args, **kwargs):
warnings.warn(
"django.contrib.gis.admin.GeoModelAdmin and OSMGeoAdmin are "
"deprecated in favor of django.contrib.admin.ModelAdmin and "
"django.contrib.gis.admin.GISModelAdmin.",
RemovedInDjango50Warning,
stacklevel=2,
)
super().__init__(*args, **kwargs)
@property
def media(self):
"Injects OpenLayers JavaScript into the admin."
return super().media + Media(js=[self.openlayers_url] + self.extra_js)
def formfield_for_dbfield(self, db_field, request, **kwargs):
"""
Overloaded from ModelAdmin so that an OpenLayersWidget is used
for viewing/editing 2D GeometryFields (OpenLayers 2 does not support
3D editing).
"""
if isinstance(db_field, models.GeometryField) and db_field.dim < 3:
# Setting the widget with the newly defined widget.
kwargs["widget"] = self.get_map_widget(db_field)
return db_field.formfield(**kwargs)
else:
return super().formfield_for_dbfield(db_field, request, **kwargs)
def get_map_widget(self, db_field):
"""
Return a subclass of the OpenLayersWidget (or whatever was specified
in the `widget` attribute) using the settings from the attributes set
in this class.
"""
is_collection = db_field.geom_type in (
"MULTIPOINT",
"MULTILINESTRING",
"MULTIPOLYGON",
"GEOMETRYCOLLECTION",
)
if is_collection:
if db_field.geom_type == "GEOMETRYCOLLECTION":
collection_type = "Any"
else:
collection_type = OGRGeomType(db_field.geom_type.replace("MULTI", ""))
else:
collection_type = "None"
class OLMap(self.widget):
template_name = self.map_template
geom_type = db_field.geom_type
wms_options = ""
if self.wms_options:
wms_options = ["%s: '%s'" % pair for pair in self.wms_options.items()]
wms_options = ", %s" % ", ".join(wms_options)
params = {
"default_lon": self.default_lon,
"default_lat": self.default_lat,
"default_zoom": self.default_zoom,
"display_wkt": self.debug or self.display_wkt,
"geom_type": OGRGeomType(db_field.geom_type),
"field_name": db_field.name,
"is_collection": is_collection,
"scrollable": self.scrollable,
"layerswitcher": self.layerswitcher,
"collection_type": collection_type,
"is_generic": db_field.geom_type == "GEOMETRY",
"is_linestring": db_field.geom_type
in ("LINESTRING", "MULTILINESTRING"),
"is_polygon": db_field.geom_type in ("POLYGON", "MULTIPOLYGON"),
"is_point": db_field.geom_type in ("POINT", "MULTIPOINT"),
"num_zoom": self.num_zoom,
"max_zoom": self.max_zoom,
"min_zoom": self.min_zoom,
"units": self.units, # likely should get from object
"max_resolution": self.max_resolution,
"max_extent": self.max_extent,
"modifiable": self.modifiable,
"mouse_position": self.mouse_position,
"scale_text": self.scale_text,
"map_width": self.map_width,
"map_height": self.map_height,
"point_zoom": self.point_zoom,
"srid": self.map_srid,
"display_srid": self.display_srid,
"wms_url": self.wms_url,
"wms_layer": self.wms_layer,
"wms_name": self.wms_name,
"wms_options": wms_options,
"debug": self.debug,
}
return OLMap
# RemovedInDjango50Warning.
class OSMGeoAdmin(GeoModelAdmin):
map_template = "gis/admin/osm.html"
num_zoom = 20
map_srid = spherical_mercator_srid
max_extent = "-20037508,-20037508,20037508,20037508"
max_resolution = "156543.0339"
point_zoom = num_zoom - 6
units = "m"

View File

@ -1,31 +0,0 @@
{% block extrastyle %}
{% load i18n static %}{% get_current_language_bidi as LANGUAGE_BIDI %}
<style type="text/css">
#{{ id }}_map { width: {{ map_width }}px; height: {{ map_height }}px; }
#{{ id }}_map .aligned label { float:inherit; }
#{{ id }}_admin_map { position: relative; vertical-align: top; z-index: 0; float: {{ LANGUAGE_BIDI|yesno:"right,left" }}; }
{% if not display_wkt %}#{{ id }} { display: none; }{% endif %}
.olControlEditingToolbar .olControlModifyFeatureItemActive {
background-image: url("{% static "admin/img/gis/move_vertex_on.svg" %}");
background-repeat: no-repeat;
}
.olControlEditingToolbar .olControlModifyFeatureItemInactive {
background-image: url("{% static "admin/img/gis/move_vertex_off.svg" %}");
background-repeat: no-repeat;
}
</style>
{% endblock %}
<span id="{{ id }}_admin_map">
<script>
//<![CDATA[
{% block openlayers %}{% include "gis/admin/openlayers.js" %}{% endblock %}
//]]>
</script>
<div id="{{ id }}_map" dir="{{ LANGUAGE_BIDI|yesno:'rtl,ltr,auto' }}"></div>
{% if editable %}
<a href="javascript:{{ module }}.clearFeatures()">{% translate "Delete all Features" %}</a>
{% endif %}
{% if display_wkt %}<p>{% translate "WKT debugging window:" %} </p>{% endif %}
<textarea id="{{ id }}" class="vWKTField required" cols="150" rows="10" name="{{ name }}">{{ wkt }}</textarea>
<script>{% block init_function %}{{ module }}.init();{% endblock %}</script>
</span>

View File

@ -1,176 +0,0 @@
{% load l10n %}
OpenLayers.Projection.addTransform("EPSG:4326", "EPSG:3857", OpenLayers.Layer.SphericalMercator.projectForward);
{% block vars %}var {{ module }} = {};
{{ module }}.map = null; {{ module }}.controls = null; {{ module }}.panel = null; {{ module }}.re = new RegExp("^SRID=\\d+;(.+)", "i"); {{ module }}.layers = {};
{{ module }}.modifiable = {{ modifiable|yesno:"true,false" }};
{{ module }}.wkt_f = new OpenLayers.Format.WKT();
{{ module }}.is_collection = {{ is_collection|yesno:"true,false" }};
{{ module }}.collection_type = '{{ collection_type }}';
{{ module }}.is_generic = {{ is_generic|yesno:"true,false" }};
{{ module }}.is_linestring = {{ is_linestring|yesno:"true,false" }};
{{ module }}.is_polygon = {{ is_polygon|yesno:"true,false" }};
{{ module }}.is_point = {{ is_point|yesno:"true,false" }};
{% endblock %}
{{ module }}.get_ewkt = function(feat){
return 'SRID={{ srid|unlocalize }};' + {{ module }}.wkt_f.write(feat);
};
{{ module }}.read_wkt = function(wkt){
// OpenLayers cannot handle EWKT -- we make sure to strip it out.
// EWKT is only exposed to OL if there's a validation error in the admin.
var match = {{ module }}.re.exec(wkt);
if (match){wkt = match[1];}
return {{ module }}.wkt_f.read(wkt);
};
{{ module }}.write_wkt = function(feat){
if ({{ module }}.is_collection){ {{ module }}.num_geom = feat.geometry.components.length;}
else { {{ module }}.num_geom = 1;}
document.getElementById('{{ id }}').value = {{ module }}.get_ewkt(feat);
};
{{ module }}.add_wkt = function(event){
// This function will sync the contents of the `vector` layer with the
// WKT in the text field.
if ({{ module }}.is_collection){
var feat = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.{{ geom_type }}());
for (var i = 0; i < {{ module }}.layers.vector.features.length; i++){
feat.geometry.addComponents([{{ module }}.layers.vector.features[i].geometry]);
}
{{ module }}.write_wkt(feat);
} else {
// Make sure to remove any previously added features.
if ({{ module }}.layers.vector.features.length > 1){
old_feats = [{{ module }}.layers.vector.features[0]];
{{ module }}.layers.vector.removeFeatures(old_feats);
{{ module }}.layers.vector.destroyFeatures(old_feats);
}
{{ module }}.write_wkt(event.feature);
}
};
{{ module }}.modify_wkt = function(event){
if ({{ module }}.is_collection){
if ({{ module }}.is_point){
{{ module }}.add_wkt(event);
return;
} else {
// When modifying the selected components are added to the
// vector layer so we only increment to the `num_geom` value.
var feat = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.{{ geom_type }}());
for (var i = 0; i < {{ module }}.num_geom; i++){
feat.geometry.addComponents([{{ module }}.layers.vector.features[i].geometry]);
}
{{ module }}.write_wkt(feat);
}
} else {
{{ module }}.write_wkt(event.feature);
}
};
// Function to clear vector features and purge wkt from div
{{ module }}.deleteFeatures = function(){
{{ module }}.layers.vector.removeFeatures({{ module }}.layers.vector.features);
{{ module }}.layers.vector.destroyFeatures();
};
{{ module }}.clearFeatures = function (){
{{ module }}.deleteFeatures();
document.getElementById('{{ id }}').value = '';
{% localize off %}
{{ module }}.map.setCenter(new OpenLayers.LonLat({{ default_lon }}, {{ default_lat }}), {{ default_zoom }});
{% endlocalize %}
};
// Add Select control
{{ module }}.addSelectControl = function(){
var select = new OpenLayers.Control.SelectFeature({{ module }}.layers.vector, {'toggle' : true, 'clickout' : true});
{{ module }}.map.addControl(select);
select.activate();
};
{{ module }}.enableDrawing = function(){
{{ module }}.map.getControlsByClass('OpenLayers.Control.DrawFeature')[0].activate();
};
{{ module }}.enableEditing = function(){
{{ module }}.map.getControlsByClass('OpenLayers.Control.ModifyFeature')[0].activate();
};
// Create an array of controls based on geometry type
{{ module }}.getControls = function(lyr){
{{ module }}.panel = new OpenLayers.Control.Panel({'displayClass': 'olControlEditingToolbar'});
{{ module }}.controls = [new OpenLayers.Control.Navigation()];
if (!{{ module }}.modifiable && lyr.features.length) return;
if ({{ module }}.is_linestring || {{ module }}.is_generic){
{{ module }}.controls.push(new OpenLayers.Control.DrawFeature(lyr, OpenLayers.Handler.Path, {'displayClass': 'olControlDrawFeaturePath'}));
}
if ({{ module }}.is_polygon || {{ module }}.is_generic){
{{ module }}.controls.push(new OpenLayers.Control.DrawFeature(lyr, OpenLayers.Handler.Polygon, {'displayClass': 'olControlDrawFeaturePolygon'}));
}
if ({{ module }}.is_point || {{ module }}.is_generic){
{{ module }}.controls.push(new OpenLayers.Control.DrawFeature(lyr, OpenLayers.Handler.Point, {'displayClass': 'olControlDrawFeaturePoint'}));
}
if ({{ module }}.modifiable){
{{ module }}.controls.push(new OpenLayers.Control.ModifyFeature(lyr, {'displayClass': 'olControlModifyFeature'}));
}
};
{{ module }}.init = function(){
{% block map_options %}// The options hash, w/ zoom, resolution, and projection settings.
var options = {
{% autoescape off %}{% for item in map_options.items %} '{{ item.0 }}' : {{ item.1 }}{% if not forloop.last %},{% endif %}
{% endfor %}{% endautoescape %} };{% endblock %}
// The admin map for this geometry field.
{% block map_creation %}
{{ module }}.map = new OpenLayers.Map('{{ id }}_map', options);
// Base Layer
{{ module }}.layers.base = {% block base_layer %}new OpenLayers.Layer.WMS("{{ wms_name }}", "{{ wms_url }}", {layers: '{{ wms_layer }}'{{ wms_options|safe }}});{% endblock %}
{{ module }}.map.addLayer({{ module }}.layers.base);
{% endblock %}
{% block extra_layers %}{% endblock %}
{% if is_linestring %}OpenLayers.Feature.Vector.style["default"]["strokeWidth"] = 3; // Default too thin for linestrings. {% endif %}
{{ module }}.layers.vector = new OpenLayers.Layer.Vector(" {{ field_name }}");
{{ module }}.map.addLayer({{ module }}.layers.vector);
// Read WKT from the text field.
var wkt = document.getElementById('{{ id }}').value;
if (wkt){
// After reading into geometry, immediately write back to
// WKT <textarea> as EWKT (so that SRID is included).
var admin_geom = {{ module }}.read_wkt(wkt);
{{ module }}.write_wkt(admin_geom);
if ({{ module }}.is_collection){
// If geometry collection, add each component individually so they may be
// edited individually.
for (var i = 0; i < {{ module }}.num_geom; i++){
{{ module }}.layers.vector.addFeatures([new OpenLayers.Feature.Vector(admin_geom.geometry.components[i].clone())]);
}
} else {
{{ module }}.layers.vector.addFeatures([admin_geom]);
}
// Zooming to the bounds.
{{ module }}.map.zoomToExtent(admin_geom.geometry.getBounds());
if ({{ module }}.is_point){
{{ module }}.map.zoomTo({{ point_zoom }});
}
} else {
{% localize off %}
{{ module }}.map.setCenter(new OpenLayers.LonLat({{ default_lon }}, {{ default_lat }}), {{ default_zoom }});
{% endlocalize %}
}
// This allows editing of the geographic fields -- the modified WKT is
// written back to the content field (as EWKT, so that the ORM will know
// to transform back to original SRID).
{{ module }}.layers.vector.events.on({"featuremodified" : {{ module }}.modify_wkt});
{{ module }}.layers.vector.events.on({"featureadded" : {{ module }}.add_wkt});
{% block controls %}
// Map controls:
// Add geometry specific panel of toolbar controls
{{ module }}.getControls({{ module }}.layers.vector);
{{ module }}.panel.addControls({{ module }}.controls);
{{ module }}.map.addControl({{ module }}.panel);
{{ module }}.addSelectControl();
// Then add optional visual controls
{% if mouse_position %}{{ module }}.map.addControl(new OpenLayers.Control.MousePosition());{% endif %}
{% if scale_text %}{{ module }}.map.addControl(new OpenLayers.Control.Scale());{% endif %}
{% if layerswitcher %}{{ module }}.map.addControl(new OpenLayers.Control.LayerSwitcher());{% endif %}
// Then add optional behavior controls
{% if not scrollable %}{{ module }}.map.getControlsByClass('OpenLayers.Control.Navigation')[0].disableZoomWheel();{% endif %}
{% endblock %}
if (wkt){
if ({{ module }}.modifiable){
{{ module }}.enableEditing();
}
} else {
{{ module }}.enableDrawing();
}
};

View File

@ -1,2 +0,0 @@
{% extends "gis/admin/openlayers.html" %}
{% block openlayers %}{% include "gis/admin/osm.js" %}{% endblock %}

View File

@ -1,2 +0,0 @@
{% extends "gis/admin/openlayers.js" %}
{% block base_layer %}new OpenLayers.Layer.OSM("OpenStreetMap (Mapnik)");{% endblock %}

View File

@ -20,72 +20,3 @@ GeoDjango's admin site
The keyword arguments that would be passed to the :attr:`gis_widget`.
Defaults to an empty dictionary.
``GeoModelAdmin``
=================
.. class:: GeoModelAdmin
.. attribute:: default_lon
The default center longitude.
.. attribute:: default_lat
The default center latitude.
.. attribute:: default_zoom
The default zoom level to use. Defaults to 4.
.. attribute:: extra_js
Sequence of URLs to any extra JavaScript to include.
.. attribute:: map_template
Override the template used to generate the JavaScript slippy map.
Default is ``'gis/admin/openlayers.html'``.
.. attribute:: map_width
Width of the map, in pixels. Defaults to 600.
.. attribute:: map_height
Height of the map, in pixels. Defaults to 400.
.. attribute:: openlayers_url
Link to the URL of the OpenLayers JavaScript. Defaults to
``'https://cdnjs.cloudflare.com/ajax/libs/openlayers/2.13.1/OpenLayers.js'``.
.. attribute:: modifiable
Defaults to ``True``. When set to ``False``, disables editing of
existing geometry fields in the admin.
.. note::
This is different from adding the geometry field to
:attr:`~django.contrib.admin.ModelAdmin.readonly_fields`,
which will only display the WKT of the geometry. Setting
``modifiable=False``, actually displays the geometry in a map,
but disables the ability to edit its vertices.
.. deprecated:: 4.0
This class is deprecated. Use :class:`~django.contrib.admin.ModelAdmin`
instead.
``OSMGeoAdmin``
===============
.. class:: OSMGeoAdmin
A subclass of :class:`GeoModelAdmin` that uses a Spherical Mercator projection
with `OpenStreetMap <https://www.openstreetmap.org/>`_ street data tiles.
.. deprecated:: 4.0
This class is deprecated. Use :class:`GISModelAdmin` instead.

View File

@ -294,6 +294,9 @@ to remove usage of these features.
* ``django.db.models.functions.TruncQuarter()``
* ``django.db.models.functions.TruncYear()``
* The ``django.contrib.gis.admin.GeoModelAdmin`` and ``OSMGeoAdmin`` classes
are removed.
See :ref:`deprecated-features-4.1` for details on these changes, including how
to remove usage of these features.

View File

@ -4,5 +4,3 @@ except ImportError:
from django.contrib import admin
admin.GISModelAdmin = admin.ModelAdmin
# RemovedInDjango50Warning.
admin.OSMGeoAdmin = admin.ModelAdmin

View File

@ -1,5 +0,0 @@
from django.contrib.gis import admin
class UnmodifiableAdmin(admin.OSMGeoAdmin):
modifiable = False

View File

@ -1,21 +0,0 @@
from django.contrib.gis.db import models
from django.test import ignore_warnings
from django.utils.deprecation import RemovedInDjango50Warning
from ..admin import admin
class City(models.Model):
name = models.CharField(max_length=30)
point = models.PointField()
class Meta:
app_label = "geoadmini_deprecated"
def __str__(self):
return self.name
site = admin.AdminSite(name="admin_gis")
with ignore_warnings(category=RemovedInDjango50Warning):
site.register(City, admin.OSMGeoAdmin)

View File

@ -1,132 +0,0 @@
from django.contrib.gis import admin
from django.contrib.gis.geos import Point
from django.test import SimpleTestCase, ignore_warnings, override_settings
from django.utils.deprecation import RemovedInDjango50Warning
from .admin import UnmodifiableAdmin
from .models import City, site
@ignore_warnings(category=RemovedInDjango50Warning)
@override_settings(ROOT_URLCONF="django.contrib.gis.tests.geoadmin.urls")
class GeoAdminTest(SimpleTestCase):
def test_ensure_geographic_media(self):
geoadmin = site._registry[City]
admin_js = geoadmin.media.render_js()
self.assertTrue(any(geoadmin.openlayers_url in js for js in admin_js))
def test_olmap_OSM_rendering(self):
delete_all_btn = (
'<a href="javascript:geodjango_point.clearFeatures()">Delete all Features'
"</a>"
)
original_geoadmin = site._registry[City]
params = original_geoadmin.get_map_widget(City._meta.get_field("point")).params
result = original_geoadmin.get_map_widget(
City._meta.get_field("point")
)().render("point", Point(-79.460734, 40.18476), params)
self.assertIn(
"geodjango_point.layers.base = "
'new OpenLayers.Layer.OSM("OpenStreetMap (Mapnik)");',
result,
)
self.assertIn(delete_all_btn, result)
site.unregister(City)
site.register(City, UnmodifiableAdmin)
try:
geoadmin = site._registry[City]
params = geoadmin.get_map_widget(City._meta.get_field("point")).params
result = geoadmin.get_map_widget(City._meta.get_field("point"))().render(
"point", Point(-79.460734, 40.18476), params
)
self.assertNotIn(delete_all_btn, result)
finally:
site.unregister(City)
site.register(City, original_geoadmin.__class__)
def test_olmap_WMS_rendering(self):
geoadmin = admin.GeoModelAdmin(City, site)
result = geoadmin.get_map_widget(City._meta.get_field("point"))().render(
"point", Point(-79.460734, 40.18476)
)
self.assertIn(
'geodjango_point.layers.base = new OpenLayers.Layer.WMS("OpenLayers WMS", '
'"http://vmap0.tiles.osgeo.org/wms/vmap0", '
"{layers: 'basic', format: 'image/jpeg'});",
result,
)
def test_olwidget_has_changed(self):
"""
Changes are accurately noticed by OpenLayersWidget.
"""
geoadmin = site._registry[City]
form = geoadmin.get_changelist_form(None)()
has_changed = form.fields["point"].has_changed
initial = Point(13.4197458572965953, 52.5194108501149799, srid=4326)
data_same = "SRID=3857;POINT(1493879.2754093995 6894592.019687599)"
data_almost_same = "SRID=3857;POINT(1493879.2754093990 6894592.019687590)"
data_changed = "SRID=3857;POINT(1493884.0527237 6894593.8111804)"
self.assertTrue(has_changed(None, data_changed))
self.assertTrue(has_changed(initial, ""))
self.assertFalse(has_changed(None, ""))
self.assertFalse(has_changed(initial, data_same))
self.assertFalse(has_changed(initial, data_almost_same))
self.assertTrue(has_changed(initial, data_changed))
def test_olwidget_empty_string(self):
geoadmin = site._registry[City]
form = geoadmin.get_changelist_form(None)({"point": ""})
with self.assertNoLogs("django.contrib.gis", "ERROR"):
output = str(form["point"])
self.assertInHTML(
'<textarea id="id_point" class="vWKTField required" cols="150"'
' rows="10" name="point"></textarea>',
output,
)
def test_olwidget_invalid_string(self):
geoadmin = site._registry[City]
form = geoadmin.get_changelist_form(None)({"point": "INVALID()"})
with self.assertLogs("django.contrib.gis", "ERROR") as cm:
output = str(form["point"])
self.assertInHTML(
'<textarea id="id_point" class="vWKTField required" cols="150"'
' rows="10" name="point"></textarea>',
output,
)
self.assertEqual(len(cm.records), 1)
self.assertEqual(
cm.records[0].getMessage(),
"Error creating geometry from value 'INVALID()' (String input "
"unrecognized as WKT EWKT, and HEXEWKB.)",
)
class DeprecationTests(SimpleTestCase):
def test_warning(self):
class DeprecatedOSMGeoAdmin(admin.OSMGeoAdmin):
pass
class DeprecatedGeoModelAdmin(admin.GeoModelAdmin):
pass
msg = (
"django.contrib.gis.admin.GeoModelAdmin and OSMGeoAdmin are "
"deprecated in favor of django.contrib.admin.ModelAdmin and "
"django.contrib.gis.admin.GISModelAdmin."
)
with self.assertRaisesMessage(RemovedInDjango50Warning, msg):
DeprecatedOSMGeoAdmin(City, site)
with self.assertRaisesMessage(RemovedInDjango50Warning, msg):
DeprecatedGeoModelAdmin(City, site)
def test_openlayerswidget_warning(self):
msg = "django.contrib.gis.admin.OpenLayersWidget is deprecated."
with self.assertRaisesMessage(RemovedInDjango50Warning, msg):
admin.OpenLayersWidget()

View File

@ -1,6 +0,0 @@
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path("admin/", include(admin.site.urls)),
]