mirror of
https://github.com/django/django.git
synced 2024-12-22 17:16:24 +00:00
Fixed #30049 -- Initialized GIS widgets when admin inlines are added.
This commit is contained in:
parent
a57596e443
commit
a02b4ce19f
@ -231,3 +231,29 @@ class MapWidget {
|
||||
document.getElementById(this.options.id).value = jsonFormat.writeGeometry(geometry);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
function initMapWidgetAfterInlineAdd(event) {
|
||||
const formsetIndex = event.srcElement.id.split('-').pop();
|
||||
event.target.querySelectorAll(".dj_map_wrapper").forEach((wrapper) => {
|
||||
wrapper.querySelector(".dj_map").innerHTML = "";
|
||||
const options = window[wrapper.dataset.widgetoptions];
|
||||
const newOptions = {};
|
||||
for (const key in options) {
|
||||
if (options[key].includes && options[key].includes("__prefix__")) {
|
||||
newOptions[key] = options[key].replace( "__prefix__", formsetIndex);
|
||||
} else {
|
||||
newOptions[key] = options[key];
|
||||
}
|
||||
}
|
||||
new MapWidget(newOptions);
|
||||
});
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
document.querySelectorAll(".dj_map_wrapper").forEach((wrapper) => {
|
||||
const options = window[wrapper.dataset.widgetoptions];
|
||||
new MapWidget(options);
|
||||
});
|
||||
document.addEventListener('formset:added', initMapWidgetAfterInlineAdd);
|
||||
});
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{% load i18n l10n %}
|
||||
|
||||
<div id="{{ id }}_div_map" class="dj_map_wrapper">
|
||||
<div id="{{ id }}_div_map" class="dj_map_wrapper" data-widgetoptions="{{ module }}Options">
|
||||
<div id="{{ id }}_map" class="dj_map"></div>
|
||||
{% if not disabled %}<span class="clear_features"><a href="">{% translate "Delete all Features" %}</a></span>{% endif %}
|
||||
{% if display_raw %}<p>{% translate "Debugging window (serialized value)" %}</p>{% endif %}
|
||||
@ -27,6 +27,6 @@
|
||||
name: '{{ name }}'
|
||||
};
|
||||
{% endblock %}
|
||||
var {{ module }} = new MapWidget(options);
|
||||
window.{{ module }}Options = options;
|
||||
</script>
|
||||
</div>
|
||||
|
@ -3,8 +3,19 @@ from django.contrib.gis.db import models
|
||||
from ..admin import admin
|
||||
|
||||
|
||||
class Country(models.Model):
|
||||
name = models.CharField(max_length=30)
|
||||
|
||||
class Meta:
|
||||
app_label = "geoadmin"
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class City(models.Model):
|
||||
name = models.CharField(max_length=30)
|
||||
country = models.ForeignKey(Country, on_delete=models.CASCADE)
|
||||
point = models.PointField()
|
||||
|
||||
class Meta:
|
||||
@ -23,11 +34,20 @@ class CityAdminCustomWidgetKwargs(admin.GISModelAdmin):
|
||||
}
|
||||
|
||||
|
||||
class CityInline(admin.TabularInline):
|
||||
model = City
|
||||
|
||||
|
||||
class CountryAdmin(admin.ModelAdmin):
|
||||
inlines = [CityInline]
|
||||
|
||||
|
||||
site = admin.AdminSite(name="gis_admin_modeladmin")
|
||||
site.register(City, admin.ModelAdmin)
|
||||
|
||||
site_gis = admin.AdminSite(name="gis_admin_gismodeladmin")
|
||||
site_gis.register(City, admin.GISModelAdmin)
|
||||
site_gis.register(Country, CountryAdmin)
|
||||
|
||||
site_gis_custom = admin.AdminSite(name="gis_admin_gismodeladmin")
|
||||
site_gis_custom.register(City, CityAdminCustomWidgetKwargs)
|
||||
|
@ -1,16 +1,31 @@
|
||||
from django.contrib.admin.tests import AdminSeleniumTestCase
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.gis.geos import Point
|
||||
from django.test import SimpleTestCase, override_settings
|
||||
from django.test import TestCase, modify_settings, override_settings
|
||||
from django.test.client import RequestFactory
|
||||
from django.urls import reverse
|
||||
|
||||
from .models import City, site, site_gis, site_gis_custom
|
||||
|
||||
|
||||
@override_settings(ROOT_URLCONF="django.contrib.gis.tests.geoadmin.urls")
|
||||
class GeoAdminTest(SimpleTestCase):
|
||||
@override_settings(
|
||||
ROOT_URLCONF="django.contrib.gis.tests.geoadmin.urls",
|
||||
PASSWORD_HASHERS=["django.contrib.auth.hashers.MD5PasswordHasher"],
|
||||
)
|
||||
class GeoAdminTest(TestCase):
|
||||
admin_site = site # ModelAdmin
|
||||
factory = RequestFactory()
|
||||
|
||||
def setUp(self):
|
||||
user = User.objects.create_superuser(
|
||||
username="super", password="secret", email="super@example.com"
|
||||
)
|
||||
self.request = self.factory.get("/admin")
|
||||
self.request.user = user
|
||||
|
||||
def test_widget_empty_string(self):
|
||||
geoadmin = self.admin_site.get_model_admin(City)
|
||||
form = geoadmin.get_changelist_form(None)({"point": ""})
|
||||
form = geoadmin.get_changelist_form(self.request)({"point": ""})
|
||||
with self.assertRaisesMessage(AssertionError, "no logs"):
|
||||
with self.assertLogs("django.contrib.gis", "ERROR"):
|
||||
output = str(form["point"])
|
||||
@ -22,7 +37,7 @@ class GeoAdminTest(SimpleTestCase):
|
||||
|
||||
def test_widget_invalid_string(self):
|
||||
geoadmin = self.admin_site.get_model_admin(City)
|
||||
form = geoadmin.get_changelist_form(None)({"point": "INVALID()"})
|
||||
form = geoadmin.get_changelist_form(self.request)({"point": "INVALID()"})
|
||||
with self.assertLogs("django.contrib.gis", "ERROR") as cm:
|
||||
output = str(form["point"])
|
||||
self.assertInHTML(
|
||||
@ -39,7 +54,7 @@ class GeoAdminTest(SimpleTestCase):
|
||||
|
||||
def test_widget_has_changed(self):
|
||||
geoadmin = self.admin_site.get_model_admin(City)
|
||||
form = geoadmin.get_changelist_form(None)()
|
||||
form = geoadmin.get_changelist_form(self.request)()
|
||||
has_changed = form.fields["point"].has_changed
|
||||
|
||||
initial = Point(13.4197458572965953, 52.5194108501149799, srid=4326)
|
||||
@ -60,7 +75,7 @@ class GISAdminTests(GeoAdminTest):
|
||||
|
||||
def test_default_gis_widget_kwargs(self):
|
||||
geoadmin = self.admin_site.get_model_admin(City)
|
||||
form = geoadmin.get_changelist_form(None)()
|
||||
form = geoadmin.get_changelist_form(self.request)()
|
||||
widget = form["point"].field.widget
|
||||
self.assertEqual(widget.attrs["default_lat"], 47)
|
||||
self.assertEqual(widget.attrs["default_lon"], 5)
|
||||
@ -68,8 +83,35 @@ class GISAdminTests(GeoAdminTest):
|
||||
|
||||
def test_custom_gis_widget_kwargs(self):
|
||||
geoadmin = site_gis_custom.get_model_admin(City)
|
||||
form = geoadmin.get_changelist_form(None)()
|
||||
form = geoadmin.get_changelist_form(self.request)()
|
||||
widget = form["point"].field.widget
|
||||
self.assertEqual(widget.attrs["default_lat"], 55)
|
||||
self.assertEqual(widget.attrs["default_lon"], 37)
|
||||
self.assertEqual(widget.attrs["default_zoom"], 12)
|
||||
|
||||
|
||||
@override_settings(ROOT_URLCONF="gis_tests.geoadmin.urls")
|
||||
# GeoDjango admin not yet CSP-compatible with strict values (#25706)
|
||||
@modify_settings(MIDDLEWARE={"remove": "django.contrib.admin.tests.CSPMiddleware"})
|
||||
class GISSeleniumAdminTests(AdminSeleniumTestCase):
|
||||
available_apps = AdminSeleniumTestCase.available_apps + [
|
||||
"django.contrib.gis",
|
||||
"gis_tests.geoadmin",
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
User.objects.create_superuser(
|
||||
username="super", password="secret", email="super@example.com"
|
||||
)
|
||||
|
||||
def test_gis_widget_initalized_when_inline_added(self):
|
||||
from selenium.webdriver.common.by import By
|
||||
|
||||
self.admin_login(username="super", password="secret")
|
||||
self.selenium.get(self.live_server_url + reverse("admin:geoadmin_country_add"))
|
||||
self.assertCountSeleniumElements("tr.dynamic-city_set", 3)
|
||||
add_button = self.selenium.find_element(By.LINK_TEXT, "Add another City")
|
||||
add_button.click()
|
||||
self.assertCountSeleniumElements("tr.dynamic-city_set", 4)
|
||||
map_div = self.selenium.find_element(By.ID, "id_city_set-3-point_map")
|
||||
self.assertCountSeleniumElements(".ol-layer", 1, root_element=map_div)
|
||||
|
@ -1,6 +1,7 @@
|
||||
from django.contrib import admin
|
||||
from django.urls import include, path
|
||||
from django.urls import path
|
||||
|
||||
from .models import site_gis
|
||||
|
||||
urlpatterns = [
|
||||
path("admin/", include(admin.site.urls)),
|
||||
path("admin/", site_gis.urls),
|
||||
]
|
||||
|
@ -257,7 +257,8 @@ class SpecializedFieldTest(SimpleTestCase):
|
||||
"""
|
||||
self.assertTrue(form_instance.is_valid())
|
||||
rendered = form_instance.as_p()
|
||||
self.assertIn("new MapWidget(options);", rendered)
|
||||
field_name = list(form_instance.fields.keys())[0]
|
||||
self.assertIn(f"window.geodjango_{field_name}Options = options;", rendered)
|
||||
self.assertIn("map_srid: 3857,", rendered)
|
||||
self.assertIn("gis/js/OLMapWidget.js", str(form_instance.media))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user