Opened 7 years ago
Closed 7 years ago
#29901 closed Cleanup/optimization (fixed)
InlineModelAdmin.get_formset() doesn't work with custom widgets passed in kwargs
| Reported by: | Javier Matos Odut | Owned by: | Javier Matos Odut |
|---|---|---|---|
| Component: | contrib.admin | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Accepted | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
InlineModelAdmin class has get_formset method that will create a formset based on the parameters given.
django.contrib.admin.options.InlineModelAdmin.get_formset is called with widgets and then:
django.forms.models.inlineformset_factory (Ok here as widgets are passed)
django.forms.models.modelformset_factory (Ok here as widgets are passed)
django.forms.models.modelform_factory (Ok here as widgets are passed)
django.forms.models.ModelFormMetaclass.new (Ok as widgets are passed as attrs)
django.forms.models.fields_for_model (Ok here too)
django.contrib.admin.options.BaseModelAdmin.formfield_for_dbfield (Ok here too as widget is received in kwargs)
Then here comes the problem:
django.contrib.admin.options.BaseModelAdmin.formfield_for_foreignkey
def formfield_for_foreignkey(self, db_field, request, **kwargs):
"""
Get a form Field for a ForeignKey.
"""
db = kwargs.get('using')
if db_field.name in self.get_autocomplete_fields(request):
kwargs['widget'] = AutocompleteSelect(db_field.remote_field, self.admin_site, using=db)
elif db_field.name in self.raw_id_fields:
kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.remote_field, self.admin_site, using=db)
elif db_field.name in self.radio_fields:
kwargs['widget'] = widgets.AdminRadioSelect(attrs={
'class': get_ul_class(self.radio_fields[db_field.name]),
})
kwargs['empty_label'] = _('None') if db_field.blank else None
if 'queryset' not in kwargs:
queryset = self.get_field_queryset(db, db_field, request)
if queryset is not None:
kwargs['queryset'] = queryset
return db_field.formfield(**kwargs)
This code just ignores the widget sent.
How to fix this? Just change that method to the following:
def formfield_for_foreignkey(self, db_field, request, **kwargs):
"""
Get a form Field for a ForeignKey.
"""
db = kwargs.get('using')
if 'widget' not in kwargs:
if db_field.name in self.get_autocomplete_fields(request):
kwargs['widget'] = AutocompleteSelect(db_field.remote_field, self.admin_site, using=db)
elif db_field.name in self.raw_id_fields:
kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.remote_field, self.admin_site, using=db)
elif db_field.name in self.radio_fields:
kwargs['widget'] = widgets.AdminRadioSelect(attrs={
'class': get_ul_class(self.radio_fields[db_field.name]),
})
kwargs['empty_label'] = _('None') if db_field.blank else None
if 'queryset' not in kwargs:
queryset = self.get_field_queryset(db, db_field, request)
if queryset is not None:
kwargs['queryset'] = queryset
return db_field.formfield(**kwargs)
With if 'widget' not in kwargs I let any widget set to be used by default instead of assigning a new one. That is the only change to fix it. This way now I am able to use my TabularInline and override get_formset to show my fields with custom widgets.
Attachments (1)
Change History (4)
by , 7 years ago
| Attachment: | mypatch.diff added |
|---|
comment:1 by , 7 years ago
| Easy pickings: | unset |
|---|---|
| Needs tests: | set |
| Summary: | InlineModelAdmin.get_formset do not work with custom widgets passed in kwargs → InlineModelAdmin.get_formset() doesn't work with custom widgets passed in kwargs |
| Triage Stage: | Unreviewed → Accepted |
| Type: | Uncategorized → Cleanup/optimization |
Can you add a test to your PR and then uncheck "Needs tests" on the ticket?
comment:2 by , 7 years ago
| Needs tests: | unset |
|---|---|
| Owner: | changed from to |
| Status: | new → assigned |
| Version: | 2.1 → master |
Patch to fix the issue