Opened 3 months ago
Closed 3 months ago
#35696 closed Bug (invalid)
ModelAdmin is overruling the fields of ModelForm
Reported by: | Jurrian Tromp | Owned by: | |
---|---|---|---|
Component: | Forms | Version: | 4.2 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
It seems that in ModelForm both field_order
and Meta.fields
ordering is being overruled by the admin change view. When rendering, the form
object initially has the correct order, but when admin_form
(django.contrib.admin.options:1826) is created, the fieldsets
(django.contrib.admin.options:1781) coming from get_fieldsets()
overrides the correct order in form.fields
.
Something similar in #19514 has been reported before, more or less saying that ModelAdmin order should be leading. The problem with this however is that the reason you have a ModelForm here this way is because you try to do something more specialized. Consider this:
class Message(models.Model): some_readonly = models.CharField(...) overruled_model_m2m_field = models.ManyToManyField(through=SomeModel, ...) class MessageForm(forms.ModelForm): some_form_field = forms.CharField() overruled_model_m2m_field = forms.CharField() field_order = ['some_form_field', 'overruled_model_m2m_field'] class Meta: model = Message fields = ['some_form_field', 'overruled_model_m2m_field'] exclude = ['some_readonly'] class MessageAdmin(admin.ModelAdmin): readonly_fields = ['some_readonly'] form = MessageForm
Resulting in the following unexpected behavior:
- For the fields MessageForm is ignored for the most part, MessageAdmin.get_fields() is de-facto shown.
- ModelAdmin
readonly_fields
are shown, even when they are excluded in the ModelForm. MessageForm.field_order
has no effect when used in an admin view.
- ModelAdmin
- When a model field has
through
, it is not shown, as it should be an inline. Although it will be added to the fields again in the form (MessageForm.overruled_model_m2m_field
)- This makes it appear "randomly" in the ordering as it is updated to the end of base_fields (django.forms.models:324)
Expected behavior:
MessageForm
takes precedence overMessageAdmin
.- Excluded fields are not shown
ModelForm.Meta.fields
andModelForm.field_order
are used in favor ofModelAdmin.get_fields()
- a. Fields with a through that are also specified in the form itself are ordered correctly according to 1b.
There are workarounds to get both the field order and readonly fields right, which comes down to defining MessageAdmin.get_fields()
and/or MessageAdmin.get_readonly_fields()
, to take full control. However, IMHO this should not be the default.
Change History (2)
comment:1 by , 3 months ago
Description: | modified (diff) |
---|
comment:2 by , 3 months ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
This is the expected behaviour as far as I can see. The ModelAdmin.form docs state that the
fields
meta option is ignored on any provided form. (The provided form class is used as the base, but fields are derived from the admin optionsfields
/fieldsets
.)If you want to bypass the form generation you should override
get_form()
.I'd suggest following up in TicketClosingReasons/UseSupportChannels if you need to dig further.