#33321: Django admin doesn't render "add another / modify" icons next to
ForeignKey
fields that are declared in the ModelForm
-----------------------------------------+------------------------
Reporter: James Pic | Owner: nobody
Type: Bug | Status: new
Component: contrib.admin | Version: 3.2
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 1 |
-----------------------------------------+------------------------
Django admin renders very convenient "add another" and "modify" buttons
next to ForeignKey fields when the admin uses a form like this:
{{{
class TForm(forms.ModelForm):
class Meta:
model = TModel
fields = ('name', 'test')
widgets = {
'test': MyWidget(),
}
class TAdmin(admin.ModelAdmin):
form = TForm
}}}
BUT, it won't if my field is declared in the ModelForm as such:
{{{
class TForm(forms.ModelForm):
test = forms.ModelChoiceField(
widget=MyWidget(),
queryset=Some.objects.all(),
)
class Meta:
model = TModel
fields = ('name', 'test')
class TAdmin(admin.ModelAdmin):
form = TForm
}}}
This is confusing behavior is not documented AFAIK, and users have been
opening issues on github about this, I just debugged it out by chance
because it was in my way.
This is because Django admin:
- Does the formfield.widget = RelatedFieldWidgetWrapper(formfield.widget)
decoration on generated fields
- And then overrides generated fields with the declared fields
As you can see in this trace session:
{{{
> /home/jpic/.local/lib/python3.9/site-
packages/django/forms/models.py(279)__new__()
-> fields.update(new_class.declared_fields)
(Pdb) l
274 message = message % (', '.join(missing_fields),
275 opts.model.__name__)
276 raise FieldError(message)
277 # Override default model fields with any custom
declared ones
278 # (plus, include all the other declared fields).
279 -> fields.update(new_class.declared_fields)
280 else:
281 fields = new_class.declared_fields
282
283 new_class.base_fields = fields
284
(Pdb) fields
{'name': <django.forms.fields.CharField object at 0x7f0a251cf0d0>, 'test':
<django.forms.models.ModelChoiceField object at 0x7f0a251cf9a0>}
(Pdb) fields.declared_fields
*** AttributeError: 'dict' object has no attribute 'declared_fields'
(Pdb) new_class.declared_fields
{'test': <dal_alight.fields.ModelAlight object at 0x7f0a283b6460>}
(Pdb) new_class.declared_fields['test'].widget
<dal_alight.fields.ModelAlightWidget object at 0x7f0a283b6520>
(Pdb) fields['test'].widget
<django.contrib.admin.widgets.RelatedFieldWidgetWrapper object at
0x7f0a251cfdf0>
}}}
I believe that Django should always decorate related field widgets with
RelatedFieldWidgetWrapper, unless the widget is explicitely incompatible
with it. The meta code for this proposal is: if not
getattr(formfield.widget,
'incompatible_with_related_field_widget_wrapper', False): formfield.widget
= RelatedFieldWidgetWrapper(formfield.widget)
--
Ticket URL: <https://code.djangoproject.com/ticket/33321>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/047.05202d99da6261109788e43104ecbb0a%40djangoproject.com.