get_fieldsets not hooked in properly
|Reported by:||Melvyn Sopacua||Owned by:||loic84|
|Has patch:||yes||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
The get_fieldsets hook on a ModelAdmin class is not hooked in properly.
When a ModelAdmin does not declare fieldsets nor fields, but only constructs
it's fieldsets using the get_fieldsets method, get_form() does not initialize
fieldsets nor ModelAdmin.form.fields which results in all Model fields being
validated and cleaned before one gets to save_model.
The error is caused as follows:
- in ModelAdmin.add_view, a call is made to form.is_valid() which in turn calls django.forms.Form.full_clean()
- This gets to the _post_clean() method of django.forms.models.ModelForm.
- Since the ModelForm._meta has fields set to none, this results in django.forms.models.construct_instance being called with fields set to None
- construct_instance now loops over /all/ of the model's fields and validates
them before assigning the value, because the continue statement is never
if fields is not None and f.name not in fields: continue
A solution is not so simple because of the way _declared_fieldsets and
get_fieldsets are implemented and a decision has to be made on who is going to
be authoritative for "setting the fieldsets attribute and populating the
fields meta attribute".
The real world case that triggered this error implements the following logic:
- dynamically generate fieldset using several method calls each returning one 'fieldset section tuple' to allow models derived from the same base model to add fields to a section.
- if the instance for get_fieldset is None (and thus the add_view) do not add the fields that can be determined automatically.
- attach automatically determined values as properties to the model in save_model().
Test case exposing the bug is attached.
Change History (12)
comment:1 Changed 4 years ago by
|Patch needs improvement:||unset|
comment:5 Changed 3 years ago by
|Owner:||changed from nobody to loic84|
|Status:||new → assigned|