#3489 closed (fixed)
Altering self.fields in Form.__init__() fails
| Reported by: | Ronny Pfannschmidt | Owned by: | Jonathan Buchanan |
|---|---|---|---|
| Component: | Forms | Version: | dev |
| Severity: | 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 (last modified by )
take a look at the test
""" >>> TestForm({'text':"foo"}).is_valid() True >>> TestForm({'text':"foo"},need_name=True).is_valid() False >>> TestForm({'text':"foo"}).is_valid() #this one will fail True """ from django.newforms import * class TestForm(Form): name = CharField(max_length=30) text = CharField(widget=Textarea) def __init__(self,*k,**kw): need_name=kw.pop("need_name",False) Form.__init__(self,*k,**kw) if need_name: self.fields["name"].required=True
Just assigning need_name to self.fields["name"].required would create a race condition for multithreaded servers.
Attachments (2)
Change History (11)
comment:1 by , 19 years ago
| Description: | modified (diff) |
|---|---|
| Summary: | altering local newforms Formfields fails cause self.fields isnt a deep copy → Altering self.fields in Form.__init__() fails |
| Triage Stage: | Unreviewed → Accepted |
comment:2 by , 19 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
comment:3 by , 19 years ago
| Resolution: | fixed |
|---|---|
| Status: | closed → reopened |
Should copy.deepcopy() be used instead? I ran into problems when modifying widgets, as each field's widget will still be a reference rather than a copy.
from django import newforms as forms
class UserForm(forms.Form):
username = forms.CharField(max_length=30)
def __init__(self, disable_name=False, *args, **kwargs):
super(UserForm, self).__init__(*args, **kwargs)
if disable_name:
self.fields['username'].widget.attrs['disabled'] = 'disabled'
>>> f1 = UserForm()
>>> print f1['username']
<input id="id_username" type="text" name="username" maxlength="30" />
>>> f2 = UserForm(disable_name=True)
>>> print f2['username']
<input disabled="disabled" id="id_username" type="text" name="username" maxlength="30" />
>>> print f1['username']
<input disabled="disabled" id="id_username" type="text" name="username" maxlength="30" />
by , 19 years ago
| Attachment: | deepcopy.diff added |
|---|
Copying of fields with deepcopy and regression test
comment:4 by , 18 years ago
| Has patch: | set |
|---|
comment:5 by , 18 years ago
| Owner: | changed from to |
|---|---|
| Status: | reopened → new |
Reassigning to myself since I've already written a patch and regression tests - will check if it still applies cleanly.
by , 18 years ago
| Attachment: | sprint-patch1.diff added |
|---|
Previous patch no longer works due to a deepcopy error
comment:6 by , 18 years ago
The deepcopy implementation I've just attached a patch for seems like a bit of a hack to me, but the tests pass - can I get a second opinion?
comment:7 by , 18 years ago
I don't think this patch is hackish at all. It's exactly what is required when you write a deepcopy method: copy the bits you need and that's it. This is fine.
comment:8 by , 18 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
comment:9 by , 18 years ago
| Reporter: | changed from to |
|---|
Fixed formatting in description.