diff --git a/django/contrib/gis/admin/__init__.py b/django/contrib/gis/admin/__init__.py index 2c3de6f4c5..4837de2029 100644 --- a/django/contrib/gis/admin/__init__.py +++ b/django/contrib/gis/admin/__init__.py @@ -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", ] diff --git a/django/contrib/gis/admin/options.py b/django/contrib/gis/admin/options.py index 9eb6af6335..eece24129b 100644 --- a/django/contrib/gis/admin/options.py +++ b/django/contrib/gis/admin/options.py @@ -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" diff --git a/django/contrib/gis/templates/gis/admin/openlayers.html b/django/contrib/gis/templates/gis/admin/openlayers.html deleted file mode 100644 index 6943a5beae..0000000000 --- a/django/contrib/gis/templates/gis/admin/openlayers.html +++ /dev/null @@ -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> diff --git a/django/contrib/gis/templates/gis/admin/openlayers.js b/django/contrib/gis/templates/gis/admin/openlayers.js deleted file mode 100644 index dd00bfd70a..0000000000 --- a/django/contrib/gis/templates/gis/admin/openlayers.js +++ /dev/null @@ -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(); - } -}; diff --git a/django/contrib/gis/templates/gis/admin/osm.html b/django/contrib/gis/templates/gis/admin/osm.html deleted file mode 100644 index 63c32702ec..0000000000 --- a/django/contrib/gis/templates/gis/admin/osm.html +++ /dev/null @@ -1,2 +0,0 @@ -{% extends "gis/admin/openlayers.html" %} -{% block openlayers %}{% include "gis/admin/osm.js" %}{% endblock %} diff --git a/django/contrib/gis/templates/gis/admin/osm.js b/django/contrib/gis/templates/gis/admin/osm.js deleted file mode 100644 index 16a5773074..0000000000 --- a/django/contrib/gis/templates/gis/admin/osm.js +++ /dev/null @@ -1,2 +0,0 @@ -{% extends "gis/admin/openlayers.js" %} -{% block base_layer %}new OpenLayers.Layer.OSM("OpenStreetMap (Mapnik)");{% endblock %} diff --git a/docs/ref/contrib/gis/admin.txt b/docs/ref/contrib/gis/admin.txt index 8446291ae0..9954f69f90 100644 --- a/docs/ref/contrib/gis/admin.txt +++ b/docs/ref/contrib/gis/admin.txt @@ -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. diff --git a/docs/releases/5.0.txt b/docs/releases/5.0.txt index 2a0918b287..c1d6f25088 100644 --- a/docs/releases/5.0.txt +++ b/docs/releases/5.0.txt @@ -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. diff --git a/tests/gis_tests/admin.py b/tests/gis_tests/admin.py index 2662013f78..a0fd807d44 100644 --- a/tests/gis_tests/admin.py +++ b/tests/gis_tests/admin.py @@ -4,5 +4,3 @@ except ImportError: from django.contrib import admin admin.GISModelAdmin = admin.ModelAdmin - # RemovedInDjango50Warning. - admin.OSMGeoAdmin = admin.ModelAdmin diff --git a/tests/gis_tests/geoadmin_deprecated/__init__.py b/tests/gis_tests/geoadmin_deprecated/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/gis_tests/geoadmin_deprecated/admin.py b/tests/gis_tests/geoadmin_deprecated/admin.py deleted file mode 100644 index ab39c28885..0000000000 --- a/tests/gis_tests/geoadmin_deprecated/admin.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.contrib.gis import admin - - -class UnmodifiableAdmin(admin.OSMGeoAdmin): - modifiable = False diff --git a/tests/gis_tests/geoadmin_deprecated/models.py b/tests/gis_tests/geoadmin_deprecated/models.py deleted file mode 100644 index 5e84d0c9fa..0000000000 --- a/tests/gis_tests/geoadmin_deprecated/models.py +++ /dev/null @@ -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) diff --git a/tests/gis_tests/geoadmin_deprecated/tests.py b/tests/gis_tests/geoadmin_deprecated/tests.py deleted file mode 100644 index d6bea7a690..0000000000 --- a/tests/gis_tests/geoadmin_deprecated/tests.py +++ /dev/null @@ -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() diff --git a/tests/gis_tests/geoadmin_deprecated/urls.py b/tests/gis_tests/geoadmin_deprecated/urls.py deleted file mode 100644 index ce237dbfd1..0000000000 --- a/tests/gis_tests/geoadmin_deprecated/urls.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.contrib import admin -from django.urls import include, path - -urlpatterns = [ - path("admin/", include(admin.site.urls)), -]