Opened 14 years ago
Closed 14 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 , 14 years ago
| Attachment: | reference_form_initial's_shadow.diff added |
|---|
comment:1 by , 14 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 , 14 years ago
| Needs tests: | set |
|---|---|
| Triage Stage: | Unreviewed → Accepted |
comment:3 by , 14 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 , 14 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 , 14 years ago
| Attachment: | form_mixin_test.diff added |
|---|
Test case to ensure get_initial() returns a fresh dict
comment:6 by , 14 years ago
| milestone: | → 1.4 |
|---|
by , 14 years ago
| Attachment: | formmixin_change_documented.diff added |
|---|
documenting behaviour change in the docs
comment:8 by , 14 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 , 14 years ago
| Needs tests: | unset |
|---|
comment:11 by , 14 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().def get_initial(self): result = {} if self.get_object().kickoff_date == None: result['kickoff_date'] = datetime.date.today() result.update(super(..., self).get_initial()) return resultI'm not sufficiently familiar with the generic view to make a decision here, but either the code or the docs must be improved.