diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index a25814b5fb..f959a8dc48 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -314,8 +314,12 @@ class BaseModelAdmin(metaclass=forms.MediaDefiningClass): kwargs["queryset"] = queryset form_field = db_field.formfield(**kwargs) - if isinstance(form_field.widget, SelectMultiple) and not isinstance( - form_field.widget, (CheckboxSelectMultiple, AutocompleteSelectMultiple) + if ( + isinstance(form_field.widget, SelectMultiple) + and form_field.widget.allow_multiple_selected + and not isinstance( + form_field.widget, (CheckboxSelectMultiple, AutocompleteSelectMultiple) + ) ): msg = _( "Hold down “Control”, or “Command” on a Mac, to select more than one." diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py index cce759a9c8..5f8584a435 100644 --- a/tests/admin_widgets/tests.py +++ b/tests/admin_widgets/tests.py @@ -273,6 +273,26 @@ class AdminFormfieldForDBFieldTests(SimpleTestCase): "Hold down “Control”, or “Command” on a Mac, to select more than one.", ) + def test_m2m_widgets_no_allow_multiple_selected(self): + class NoAllowMultipleSelectedWidget(forms.SelectMultiple): + allow_multiple_selected = False + + class AdvisorAdmin(admin.ModelAdmin): + filter_vertical = ["companies"] + formfield_overrides = { + ManyToManyField: {"widget": NoAllowMultipleSelectedWidget}, + } + + self.assertFormfield( + Advisor, + "companies", + widgets.FilteredSelectMultiple, + filter_vertical=["companies"], + ) + ma = AdvisorAdmin(Advisor, admin.site) + f = ma.formfield_for_dbfield(Advisor._meta.get_field("companies"), request=None) + self.assertEqual(f.help_text, "") + @override_settings(ROOT_URLCONF="admin_widgets.urls") class AdminFormfieldForDBFieldWithRequestTests(TestDataMixin, TestCase):