Opened 13 years ago
Closed 13 years ago
#16138 closed Bug (fixed)
ModelForm's 'initial' attribute unexpectedly persists across different instances
Reported by: | Haisheng HU | Owned by: | nobody |
---|---|---|---|
Component: | Generic views | Version: | 1.3 |
Severity: | Normal | Keywords: | model form, generic view |
Cc: | hanson2010@… | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
There are two UpdateView's (or CreateView's) A and B with their corresponding ModelForm A and B. From UpdateView A the 'initial' attribute in ModelForm A was set to a certain value. After this, UpdateView B and ModelForm B were created. Now the 'initial' attribute in ModelForm B was not {}, but the same as ModelForm A.
class UpdateViewA(UpdateView): model = Project form_class = ProjectFormA ... def get_form_kwargs(self, **kwargs): kwargs = super(UpdateViewA, self).get_form_kwargs(**kwargs) if self.get_object().kickoff_date == None: kwargs['initial']['kickoff_date'] = datetime.date.today() return kwargs class UpdateViewB(UpdateView): model = Project form_class = ProjectFormB ... class ProjectFormA(ModelForm): ... class Meta: model = Project class ProjectFormB(ModelForm): ... class Meta: model = Project
Attachments (4)
Change History (16)
by , 13 years ago
Attachment: | reference_form_initial's_shadow.diff added |
---|
comment:1 by , 13 years ago
Cc: | added |
---|---|
Keywords: | model form generic view added |
Summary: | ModelForm's 'initial' attribute expectedly persists cross different instances → ModelForm's 'initial' attribute expectedly persists across different instances |
comment:2 by , 13 years ago
Needs tests: | set |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:3 by , 13 years ago
Summary: | ModelForm's 'initial' attribute expectedly persists across different instances → ModelForm's 'initial' attribute unexpectedly persists across different instances |
---|
The alternative solution raised by @aaugustin is feasible, although it's not so straightforward to construct a local dict and update it with a super class method.
Some people adopted the get_form_kwargs
way:
http://stackoverflow.com/questions/4512254/user-current-user-on-new-django-class-views-forms
Just my 2 cents.
comment:4 by , 13 years ago
Needs documentation: | set |
---|---|
UI/UX: | unset |
get_initial
shouldn't return an object that's unsafe to mutate, and I can't see a compelling reason for it to return an immutable object. The greatest flexibility would be afforded by a method as in the patch since it allows you to alter self.initial
if you so desire, but also prevents the gotcha case of accidentally mutating the initial data for the entire process.
This patch still needs a test case, and a note in the documentation would also be helpful.
by , 13 years ago
Attachment: | form_mixin_test.diff added |
---|
Test case to ensure get_initial() returns a fresh dict
comment:6 by , 13 years ago
milestone: | → 1.4 |
---|
by , 13 years ago
Attachment: | formmixin_change_documented.diff added |
---|
documenting behaviour change in the docs
comment:8 by , 13 years ago
Needs documentation: | unset |
---|
Documentation added. I've stated '1.4' in my docs patch, although I was unsure. Should it say 'trunk' instead?
comment:10 by , 13 years ago
Needs tests: | unset |
---|
comment:11 by , 13 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
One could expect that the accessor
get_initial()
return an object value that can be safely mutated. Your patch achieves this.The alternative is to forbid mutating the result of
get_initial()
in the documentation. You would have to overrideget_initial()
instead ofget_form_kwargs()
.I'm not sufficiently familiar with the generic view to make a decision here, but either the code or the docs must be improved.