From 719a42b589d7551fc84708044b9e984ce723c8a2 Mon Sep 17 00:00:00 2001 From: Devin Cox Date: Wed, 12 Jun 2024 11:35:12 +0200 Subject: [PATCH] Fixed #34789 -- Prevented updateRelatedSelectsOptions from adding entries to filter_horizontal chosen box. Co-authored-by: yokeshwaran1 --- .../static/admin/js/admin/RelatedObjectLookups.js | 4 ++-- django/contrib/admin/widgets.py | 2 ++ tests/admin_views/test_related_object_lookups.py | 3 +++ tests/admin_widgets/tests.py | 2 +- tests/modeladmin/tests.py | 12 ++++++++---- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js b/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js index 32e3f5b840..bc3accea37 100644 --- a/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js +++ b/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js @@ -96,8 +96,8 @@ // Extract the model from the popup url '...//add/' or // '...///change/' depending the action (add or change). const modelName = path.split('/')[path.split('/').length - (objId ? 4 : 3)]; - // Exclude autocomplete selects. - const selectsRelated = document.querySelectorAll(`[data-model-ref="${modelName}"] select:not(.admin-autocomplete)`); + // Select elements with a specific model reference and context of "available-source". + const selectsRelated = document.querySelectorAll(`[data-model-ref="${modelName}"] [data-context="available-source"]`); selectsRelated.forEach(function(select) { if (currentSelect === select) { diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py index 260ff33ca5..00e92bf42d 100644 --- a/django/contrib/admin/widgets.py +++ b/django/contrib/admin/widgets.py @@ -272,6 +272,8 @@ class RelatedFieldWidgetWrapper(forms.Widget): self.can_add_related = can_add_related # XXX: The UX does not support multiple selected values. multiple = getattr(widget, "allow_multiple_selected", False) + if not isinstance(widget, AutocompleteMixin): + self.attrs["data-context"] = "available-source" self.can_change_related = not multiple and can_change_related # XXX: The deletion UX can be confusing when dealing with cascading deletion. cascade = getattr(rel, "on_delete", None) is CASCADE diff --git a/tests/admin_views/test_related_object_lookups.py b/tests/admin_views/test_related_object_lookups.py index c10a5568d5..761819a50f 100644 --- a/tests/admin_views/test_related_object_lookups.py +++ b/tests/admin_views/test_related_object_lookups.py @@ -110,6 +110,9 @@ class SeleniumTests(AdminSeleniumTestCase): """, ) + # Check the newly added instance is not also added in the "to" box. + m2m_to = self.selenium.find_element(By.ID, "id_m2m_to") + self.assertHTMLEqual(m2m_to.get_attribute("innerHTML"), "") m2m_box = self.selenium.find_element(By.ID, "id_m2m_from") self.assertHTMLEqual( m2m_box.get_attribute("innerHTML"), diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py index 4d18849692..6f009a6f3f 100644 --- a/tests/admin_widgets/tests.py +++ b/tests/admin_widgets/tests.py @@ -948,7 +948,7 @@ class RelatedFieldWidgetWrapperTests(SimpleTestCase): output = wrapper.render("stream", "value") expected = """