mirror of
https://github.com/django/django.git
synced 2025-11-19 03:08:59 +00:00
Allow overriding widget in formfield_for_manytomany()
Align behavior with formfield_for_foreignkey() so that passing a widget param to formfield_for_manytomany() is respected. This enables custom widgets for ManyToMany fields via admin customization.
This commit is contained in:
parent
5b884d45ac
commit
b80dab3295
2 changed files with 49 additions and 10 deletions
|
|
@ -249,6 +249,7 @@ class BaseModelAdmin(metaclass=forms.MediaDefiningClass):
|
||||||
return None
|
return None
|
||||||
db = kwargs.get('using')
|
db = kwargs.get('using')
|
||||||
|
|
||||||
|
if 'widget' not in kwargs:
|
||||||
autocomplete_fields = self.get_autocomplete_fields(request)
|
autocomplete_fields = self.get_autocomplete_fields(request)
|
||||||
if db_field.name in autocomplete_fields:
|
if db_field.name in autocomplete_fields:
|
||||||
kwargs['widget'] = AutocompleteSelectMultiple(db_field.remote_field, self.admin_site, using=db)
|
kwargs['widget'] = AutocompleteSelectMultiple(db_field.remote_field, self.admin_site, using=db)
|
||||||
|
|
|
||||||
|
|
@ -184,6 +184,44 @@ class AdminFormfieldForDBFieldTests(SimpleTestCase):
|
||||||
'Hold down “Control”, or “Command” on a Mac, to select more than one.'
|
'Hold down “Control”, or “Command” on a Mac, to select more than one.'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_formfield_for_manytomany_widget_override(self):
|
||||||
|
"""
|
||||||
|
The widget can be overridden in formfield_for_manytomany().
|
||||||
|
"""
|
||||||
|
class BandAdmin(admin.ModelAdmin):
|
||||||
|
def formfield_for_manytomany(self, db_field, request, **kwargs):
|
||||||
|
if db_field.name == 'members':
|
||||||
|
kwargs['widget'] = forms.CheckboxSelectMultiple
|
||||||
|
return super().formfield_for_manytomany(db_field, request, **kwargs)
|
||||||
|
|
||||||
|
ma = BandAdmin(Band, admin.site)
|
||||||
|
ff = ma.formfield_for_dbfield(Band._meta.get_field('members'), request=None)
|
||||||
|
# Unwrap the widget wrapper if needed
|
||||||
|
if isinstance(ff.widget, widgets.RelatedFieldWidgetWrapper):
|
||||||
|
widget = ff.widget.widget
|
||||||
|
else:
|
||||||
|
widget = ff.widget
|
||||||
|
self.assertIsInstance(widget, forms.CheckboxSelectMultiple)
|
||||||
|
|
||||||
|
def test_formfield_for_foreignkey_widget_override(self):
|
||||||
|
"""
|
||||||
|
The widget can be overridden in formfield_for_foreignkey().
|
||||||
|
"""
|
||||||
|
class EventAdmin(admin.ModelAdmin):
|
||||||
|
def formfield_for_foreignkey(self, db_field, request, **kwargs):
|
||||||
|
if db_field.name == 'main_band':
|
||||||
|
kwargs['widget'] = forms.RadioSelect
|
||||||
|
return super().formfield_for_foreignkey(db_field, request, **kwargs)
|
||||||
|
|
||||||
|
ma = EventAdmin(Event, admin.site)
|
||||||
|
ff = ma.formfield_for_dbfield(Event._meta.get_field('main_band'), request=None)
|
||||||
|
# Unwrap the widget wrapper
|
||||||
|
if isinstance(ff.widget, widgets.RelatedFieldWidgetWrapper):
|
||||||
|
widget = ff.widget.widget
|
||||||
|
else:
|
||||||
|
widget = ff.widget
|
||||||
|
self.assertIsInstance(widget, forms.RadioSelect)
|
||||||
|
|
||||||
|
|
||||||
@override_settings(ROOT_URLCONF='admin_widgets.urls')
|
@override_settings(ROOT_URLCONF='admin_widgets.urls')
|
||||||
class AdminFormfieldForDBFieldWithRequestTests(TestDataMixin, TestCase):
|
class AdminFormfieldForDBFieldWithRequestTests(TestDataMixin, TestCase):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue