Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #3489 -- Changed newforms to use copy.copy() in constructing se…

…lf.fields, so changes to self.fields in a given form instance do not affect other instances

git-svn-id: http://code.djangoproject.com/svn/django/trunk@4504 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 9efa60dafbfa9f23423c6babb8de56e028f24c49 1 parent c61d7e1
@adrianholovaty adrianholovaty authored
Showing with 39 additions and 1 deletion.
  1. +2 −1  django/newforms/forms.py
  2. +37 −0 tests/regressiontests/forms/tests.py
View
3  django/newforms/forms.py
@@ -7,6 +7,7 @@
from fields import Field
from widgets import TextInput, Textarea, HiddenInput, MultipleHiddenInput
from util import flatatt, StrAndUnicode, ErrorDict, ErrorList, ValidationError
+import copy
__all__ = ('BaseForm', 'Form')
@@ -27,7 +28,7 @@ def __init__(self, data=None):
dict.__init__(self, dict(data))
def copy(self):
- return SortedDictFromList(self.items())
+ return SortedDictFromList([(k, copy.copy(v)) for k, v in self.items()])
class DeclarativeFieldsMetaclass(type):
"Metaclass that converts Field attributes to a dictionary called 'base_fields'."
View
37 tests/regressiontests/forms/tests.py
@@ -2334,6 +2334,43 @@
<tr><th>Field3:</th><td><input type="text" name="field3" /></td></tr>
<tr><th>Field4:</th><td><input type="text" name="field4" /></td></tr>
+Similarly, changes to field attributes do not persist from one Form instance
+to the next.
+>>> class Person(Form):
+... first_name = CharField(required=False)
+... last_name = CharField(required=False)
+... def __init__(self, names_required=False, *args, **kwargs):
+... super(Person, self).__init__(*args, **kwargs)
+... if names_required:
+... self.fields['first_name'].required = True
+... self.fields['last_name'].required = True
+>>> f = Person(names_required=False)
+>>> f['first_name'].field.required, f['last_name'].field.required
+(False, False)
+>>> f = Person(names_required=True)
+>>> f['first_name'].field.required, f['last_name'].field.required
+(True, True)
+>>> f = Person(names_required=False)
+>>> f['first_name'].field.required, f['last_name'].field.required
+(False, False)
+>>> class Person(Form):
+... first_name = CharField(max_length=30)
+... last_name = CharField(max_length=30)
+... def __init__(self, name_max_length=None, *args, **kwargs):
+... super(Person, self).__init__(*args, **kwargs)
+... if name_max_length:
+... self.fields['first_name'].max_length = name_max_length
+... self.fields['last_name'].max_length = name_max_length
+>>> f = Person(name_max_length=None)
+>>> f['first_name'].field.max_length, f['last_name'].field.max_length
+(30, 30)
+>>> f = Person(name_max_length=20)
+>>> f['first_name'].field.max_length, f['last_name'].field.max_length
+(20, 20)
+>>> f = Person(name_max_length=None)
+>>> f['first_name'].field.max_length, f['last_name'].field.max_length
+(30, 30)
+
HiddenInput widgets are displayed differently in the as_table(), as_ul()
and as_p() output of a Form -- their verbose names are not displayed, and a
separate row is not displayed. They're displayed in the last row of the
Please sign in to comment.
Something went wrong with that request. Please try again.