diff options
| author | SaJH <wogur981208@gmail.com> | 2025-08-27 23:34:04 +0900 |
|---|---|---|
| committer | Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> | 2025-08-29 08:38:12 +0200 |
| commit | 0be1c4575b03b9f7ac91ec9aabe0bedb542d20bc (patch) | |
| tree | 290ee172b7bdefd85c0c8e57eb03adab35da65ae | |
| parent | 550822bceea227b07445d1852c4376b663c09ea4 (diff) | |
Fixed #34624 -- Removed change, delete, and view buttons for non-Select widgets in RelatedFieldWidgetWrapper.
Signed-off-by: SaJH <wogur981208@gmail.com>
| -rw-r--r-- | django/contrib/admin/widgets.py | 13 | ||||
| -rw-r--r-- | tests/admin_widgets/tests.py | 15 |
2 files changed, 23 insertions, 5 deletions
diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py index 124f3307af..81b57f33aa 100644 --- a/django/contrib/admin/widgets.py +++ b/django/contrib/admin/widgets.py @@ -10,6 +10,7 @@ from django.conf import settings from django.core.exceptions import ValidationError from django.core.validators import URLValidator from django.db.models import CASCADE, UUIDField +from django.forms.widgets import Select from django.urls import reverse from django.urls.exceptions import NoReverseMatch from django.utils.html import smart_urlquote @@ -284,16 +285,18 @@ class RelatedFieldWidgetWrapper(forms.Widget): if can_add_related is None: can_add_related = admin_site.is_registered(rel.model) 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 + # Only single-select Select widgets are supported. + supported = not getattr( + widget, "allow_multiple_selected", False + ) and isinstance(widget, Select) + self.can_change_related = supported and can_change_related # XXX: The deletion UX can be confusing when dealing with cascading # deletion. cascade = getattr(rel, "on_delete", None) is CASCADE - self.can_delete_related = not multiple and not cascade and can_delete_related - self.can_view_related = not multiple and can_view_related + self.can_delete_related = supported and not cascade and can_delete_related + self.can_view_related = supported and can_view_related # To check if the related object is registered with this AdminSite. self.admin_site = admin_site self.use_fieldset = True diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py index 9a5c846bdd..7588c2cc32 100644 --- a/tests/admin_widgets/tests.py +++ b/tests/admin_widgets/tests.py @@ -978,6 +978,21 @@ class RelatedFieldWidgetWrapperTests(SimpleTestCase): """ self.assertHTMLEqual(output, expected) + def test_non_select_widget_cant_change_delete_related(self): + main_band = Event._meta.get_field("main_band") + widget = widgets.AdminRadioSelect() + wrapper = widgets.RelatedFieldWidgetWrapper( + widget, + main_band, + widget_admin_site, + can_add_related=True, + can_change_related=True, + can_delete_related=True, + ) + self.assertTrue(wrapper.can_add_related) + self.assertFalse(wrapper.can_change_related) + self.assertFalse(wrapper.can_delete_related) + @override_settings(ROOT_URLCONF="admin_widgets.urls") class AdminWidgetSeleniumTestCase(AdminSeleniumTestCase): |
