Opened 17 years ago
Closed 12 years ago
#8387 closed Bug (fixed)
Returning a subset of the models fields in ModelAdmin.get_fieldsets only works when also overriding get_form
| Reported by: | Owned by: | nobody | |
|---|---|---|---|
| Component: | Documentation | 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
If you return only a subset of your models fields in get_fieldsets you need to override get_form as well and set the fields or exclude attribute. Otherwise the form will expect *all* fields to be present and will either raise validation errors on the missing fields or clear them if they have blank=True.
This won't work:
class MyModelAdmin(admin.ModelAdmin): def get_fieldsets(self, request, obj=None): if obj: return [(None, {'fields': ('field_c', 'field_b')})] return [(None, {'fields': ('field_a', 'field_b', 'field_c')})]
But this will:
class MyModelAdmin(admin.ModelAdmin): def get_fieldsets(self, request, obj=None): if obj: return [(None, {'fields': ('field_c', 'field_b')})] return [(None, {'fields': ('field_a', 'field_b', 'field_c')})] def get_form(self, request, obj=None, **kwargs): if obj: defaults = {'exclude': ('field_a',)} else: defaults = {} defaults.update(kwargs) return super(MyModelAdmin, self).get_form(request, obj, **defaults)
The reason for this is that Django cannot provide a sensible default for both cases:
- Just override
get_form - Just override
get_fieldsets
In the first case get_fieldsets calls the overriden get_form and can so determine a default value for fieldsets. But this means that the default implementation of get_form cannot call get_fieldsets as this would create an infinite loop.
Which function calls the other could be discussed -- maybe overriding get_fieldsets is much more common? But in the case it stays like it is the attached patch documents the behavior.
Attachments (4)
Change History (14)
by , 17 years ago
| Attachment: | get_form+get_fieldsets-docs-00.diff added |
|---|
comment:1 by , 17 years ago
I don't know if we want to recommend flatten_fieldsets() for public use. But if we would this is the much cleaner method to use if you need to override get_form() just to work around the get_fieldsets() gotcha:
from django.contrib.admin.util import flatten_fieldsets def get_form(self, request, obj=None, **kwargs): defaults = { 'fields': flatten_fieldsets(self.get_fieldsets(request, obj)), } defaults.update(kwargs) return super(FrontpageImageOptions, self).get_form(request, obj, **defaults)
by , 17 years ago
| Attachment: | get_form+get_fieldsets-docs-01.diff added |
|---|
Updated the patch for the docs refactor
by , 17 years ago
| Attachment: | get_form+get_fieldsets-docs-02.2.diff added |
|---|
by , 17 years ago
| Attachment: | get_form+get_fieldsets-docs-02.diff added |
|---|
Alternate version using flatten_fieldsets()
comment:2 by , 17 years ago
| milestone: | 1.0 → post-1.0 |
|---|
comment:4 by , 17 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|
comment:5 by , 15 years ago
Another annoying inconsistency is that a form returned with get_form will not be respected by fieldsets argument on the ModelAdmin.
comment:6 by , 15 years ago
| Severity: | → Normal |
|---|---|
| Type: | → Bug |
comment:9 by , 12 years ago
| Component: | contrib.admin → Documentation |
|---|---|
| Has patch: | set |
comment:10 by , 12 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
"If you return only a subset of your models fields in
get_fieldsetsyou need to overrideget_formas well and set thefieldsorexcludeattribute."
I think this has been fixed since the original report. I just tried the example and a field with blank=True that was excluded using get_fieldsets was not cleared as originally reported, nor was there a ValidationError if the field had blank=False.
Documentation for get_form and get_fieldsets has also been added.
"Another annoying inconsistency is that a form returned with get_form will not be respected by fieldsets argument on the ModelAdmin."
This was fixed in #18681.
Documents get_fieldsets and get_form, gives an example each and adds a note documenting the gotcha