mirror of
https://github.com/django/django.git
synced 2025-11-18 19:01:40 +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,16 +249,17 @@ class BaseModelAdmin(metaclass=forms.MediaDefiningClass):
|
|||
return None
|
||||
db = kwargs.get('using')
|
||||
|
||||
autocomplete_fields = self.get_autocomplete_fields(request)
|
||||
if db_field.name in autocomplete_fields:
|
||||
kwargs['widget'] = AutocompleteSelectMultiple(db_field.remote_field, self.admin_site, using=db)
|
||||
elif db_field.name in self.raw_id_fields:
|
||||
kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.remote_field, self.admin_site, using=db)
|
||||
elif db_field.name in [*self.filter_vertical, *self.filter_horizontal]:
|
||||
kwargs['widget'] = widgets.FilteredSelectMultiple(
|
||||
db_field.verbose_name,
|
||||
db_field.name in self.filter_vertical
|
||||
)
|
||||
if 'widget' not in kwargs:
|
||||
autocomplete_fields = self.get_autocomplete_fields(request)
|
||||
if db_field.name in autocomplete_fields:
|
||||
kwargs['widget'] = AutocompleteSelectMultiple(db_field.remote_field, self.admin_site, using=db)
|
||||
elif db_field.name in self.raw_id_fields:
|
||||
kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.remote_field, self.admin_site, using=db)
|
||||
elif db_field.name in [*self.filter_vertical, *self.filter_horizontal]:
|
||||
kwargs['widget'] = widgets.FilteredSelectMultiple(
|
||||
db_field.verbose_name,
|
||||
db_field.name in self.filter_vertical
|
||||
)
|
||||
|
||||
if 'queryset' not in kwargs:
|
||||
queryset = self.get_field_queryset(db, db_field, request)
|
||||
|
|
|
|||
|
|
@ -184,6 +184,44 @@ class AdminFormfieldForDBFieldTests(SimpleTestCase):
|
|||
'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')
|
||||
class AdminFormfieldForDBFieldWithRequestTests(TestDataMixin, TestCase):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue