Replaced dict reprs in tests with explicit looks at each key. This should fix many spurious test failures on other VMs (first noticed on Jython).

git-svn-id: http://code.djangoproject.com/svn/django/trunk@7322 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jacob Kaplan-Moss 2008-03-19 19:11:51 +00:00
parent 6035af82d4
commit bc1f67a6de
7 changed files with 179 additions and 84 deletions

View File

@ -71,8 +71,9 @@ u'ABC123'
>>> fran.save() >>> fran.save()
>>> Employee.objects.filter(last_name__exact='Jones') >>> Employee.objects.filter(last_name__exact='Jones')
[<Employee: Dan Jones>, <Employee: Fran Jones>] [<Employee: Dan Jones>, <Employee: Fran Jones>]
>>> Employee.objects.in_bulk(['ABC123', 'XYZ456']) >>> emps = Employee.objects.in_bulk(['ABC123', 'XYZ456'])
{u'XYZ456': <Employee: Fran Jones>, u'ABC123': <Employee: Dan Jones>} >>> emps['ABC123']
<Employee: Dan Jones>
>>> b = Business(name='Sears') >>> b = Business(name='Sears')
>>> b.save() >>> b.save()

View File

@ -76,8 +76,11 @@ Article 4
# in_bulk() takes a list of IDs and returns a dictionary mapping IDs # in_bulk() takes a list of IDs and returns a dictionary mapping IDs
# to objects. # to objects.
>>> Article.objects.in_bulk([1, 2]) >>> arts = Article.objects.in_bulk([1, 2])
{1: <Article: Article 1>, 2: <Article: Article 2>} >>> arts[1]
<Article: Article 1>
>>> arts[2]
<Article: Article 2>
>>> Article.objects.in_bulk([3]) >>> Article.objects.in_bulk([3])
{3: <Article: Article 3>} {3: <Article: Article 3>}
>>> Article.objects.in_bulk([1000]) >>> Article.objects.in_bulk([1000])

View File

@ -41,25 +41,33 @@ __test__ = {'API_TESTS':u"""
True True
# Attempt to add a Musician without a first_name. # Attempt to add a Musician without a first_name.
>>> man.get_validation_errors(MultiValueDict({'last_name': ['Blakey']})) >>> man.get_validation_errors(MultiValueDict({'last_name': ['Blakey']}))['first_name']
{'first_name': [u'This field is required.']} [u'This field is required.']
# Attempt to add a Musician without a first_name and last_name. # Attempt to add a Musician without a first_name and last_name.
>>> man.get_validation_errors(MultiValueDict({})) >>> errors = man.get_validation_errors(MultiValueDict({}))
{'first_name': [u'This field is required.'], 'last_name': [u'This field is required.']} >>> errors['first_name']
[u'This field is required.']
>>> errors['last_name']
[u'This field is required.']
# Attempt to create an Album without a name or musician. # Attempt to create an Album without a name or musician.
>>> man = Album.AddManipulator() >>> man = Album.AddManipulator()
>>> man.get_validation_errors(MultiValueDict({})) >>> errors = man.get_validation_errors(MultiValueDict({}))
{'musician': [u'This field is required.'], 'name': [u'This field is required.']} >>> errors['musician']
[u'This field is required.']
>>> errors['name']
[u'This field is required.']
# Attempt to create an Album with an invalid musician. # Attempt to create an Album with an invalid musician.
>>> man.get_validation_errors(MultiValueDict({'name': ['Sallies Fforth'], 'musician': ['foo']})) >>> errors = man.get_validation_errors(MultiValueDict({'name': ['Sallies Fforth'], 'musician': ['foo']}))
{'musician': [u"Select a valid choice; 'foo' is not in [u'', u'1']."]} >>> errors['musician']
[u"Select a valid choice; 'foo' is not in [u'', u'1']."]
# Attempt to create an Album with an invalid release_date. # Attempt to create an Album with an invalid release_date.
>>> man.get_validation_errors(MultiValueDict({'name': ['Sallies Fforth'], 'musician': ['1'], 'release_date': 'today'})) >>> errors = man.get_validation_errors(MultiValueDict({'name': ['Sallies Fforth'], 'musician': ['1'], 'release_date': 'today'}))
{'release_date': [u'Enter a valid date in YYYY-MM-DD format.']} >>> errors['release_date']
[u'Enter a valid date in YYYY-MM-DD format.']
# Create an Album without a release_date (because it's optional). # Create an Album without a release_date (because it's optional).
>>> data = MultiValueDict({'name': ['Ella and Basie'], 'musician': ['1']}) >>> data = MultiValueDict({'name': ['Ella and Basie'], 'musician': ['1']})

View File

@ -234,8 +234,12 @@ We can also subclass the Meta inner class to change the fields list.
>>> f = CategoryForm({'name': 'Entertainment', 'slug': 'entertainment', 'url': 'entertainment'}) >>> f = CategoryForm({'name': 'Entertainment', 'slug': 'entertainment', 'url': 'entertainment'})
>>> f.is_valid() >>> f.is_valid()
True True
>>> f.cleaned_data >>> f.cleaned_data['url']
{'url': u'entertainment', 'name': u'Entertainment', 'slug': u'entertainment'} u'entertainment'
>>> f.cleaned_data['name']
u'Entertainment'
>>> f.cleaned_data['slug']
u'entertainment'
>>> obj = f.save() >>> obj = f.save()
>>> obj >>> obj
<Category: Entertainment> <Category: Entertainment>
@ -245,8 +249,12 @@ True
>>> f = CategoryForm({'name': "It's a test", 'slug': 'its-test', 'url': 'test'}) >>> f = CategoryForm({'name': "It's a test", 'slug': 'its-test', 'url': 'test'})
>>> f.is_valid() >>> f.is_valid()
True True
>>> f.cleaned_data >>> f.cleaned_data['url']
{'url': u'test', 'name': u"It's a test", 'slug': u'its-test'} u'test'
>>> f.cleaned_data['name']
u"It's a test"
>>> f.cleaned_data['slug']
u'its-test'
>>> obj = f.save() >>> obj = f.save()
>>> obj >>> obj
<Category: It's a test> <Category: It's a test>
@ -259,8 +267,12 @@ save() on the resulting model instance.
>>> f = CategoryForm({'name': 'Third test', 'slug': 'third-test', 'url': 'third'}) >>> f = CategoryForm({'name': 'Third test', 'slug': 'third-test', 'url': 'third'})
>>> f.is_valid() >>> f.is_valid()
True True
>>> f.cleaned_data >>> f.cleaned_data['url']
{'url': u'third', 'name': u'Third test', 'slug': u'third-test'} u'third'
>>> f.cleaned_data['name']
u'Third test'
>>> f.cleaned_data['slug']
u'third-test'
>>> obj = f.save(commit=False) >>> obj = f.save(commit=False)
>>> obj >>> obj
<Category: Third test> <Category: Third test>
@ -272,8 +284,10 @@ True
If you call save() with invalid data, you'll get a ValueError. If you call save() with invalid data, you'll get a ValueError.
>>> f = CategoryForm({'name': '', 'slug': '', 'url': 'foo'}) >>> f = CategoryForm({'name': '', 'slug': '', 'url': 'foo'})
>>> f.errors >>> f.errors['name']
{'name': [u'This field is required.'], 'slug': [u'This field is required.']} [u'This field is required.']
>>> f.errors['slug']
[u'This field is required.']
>>> f.cleaned_data >>> f.cleaned_data
Traceback (most recent call last): Traceback (most recent call last):
... ...
@ -739,8 +753,10 @@ ValidationError: [u'Select a valid choice. 4 is not one of the available choices
>>> f = PhoneNumberForm({'phone': '(312) 555-1212', 'description': 'Assistance'}) >>> f = PhoneNumberForm({'phone': '(312) 555-1212', 'description': 'Assistance'})
>>> f.is_valid() >>> f.is_valid()
True True
>>> f.cleaned_data >>> f.cleaned_data['phone']
{'phone': u'312-555-1212', 'description': u'Assistance'} u'312-555-1212'
>>> f.cleaned_data['description']
u'Assistance'
# FileField ################################################################### # FileField ###################################################################

View File

@ -41,8 +41,8 @@ __test__ = {'API_TESTS':"""
23 23
>>> p = Person(**dict(valid_params, id='foo')) >>> p = Person(**dict(valid_params, id='foo'))
>>> p.validate() >>> p.validate()['id']
{'id': [u'This value must be an integer.']} [u'This value must be an integer.']
>>> p = Person(**dict(valid_params, id=None)) >>> p = Person(**dict(valid_params, id=None))
>>> p.validate() >>> p.validate()
@ -75,8 +75,8 @@ True
False False
>>> p = Person(**dict(valid_params, is_child='foo')) >>> p = Person(**dict(valid_params, is_child='foo'))
>>> p.validate() >>> p.validate()['is_child']
{'is_child': [u'This value must be either True or False.']} [u'This value must be either True or False.']
>>> p = Person(**dict(valid_params, name=u'Jose')) >>> p = Person(**dict(valid_params, name=u'Jose'))
>>> p.validate() >>> p.validate()
@ -115,8 +115,8 @@ datetime.date(2000, 5, 3)
datetime.date(2000, 5, 3) datetime.date(2000, 5, 3)
>>> p = Person(**dict(valid_params, birthdate='foo')) >>> p = Person(**dict(valid_params, birthdate='foo'))
>>> p.validate() >>> p.validate()['birthdate']
{'birthdate': [u'Enter a valid date in YYYY-MM-DD format.']} [u'Enter a valid date in YYYY-MM-DD format.']
>>> p = Person(**dict(valid_params, favorite_moment=datetime.datetime(2002, 4, 3, 13, 23))) >>> p = Person(**dict(valid_params, favorite_moment=datetime.datetime(2002, 4, 3, 13, 23)))
>>> p.validate() >>> p.validate()
@ -143,11 +143,15 @@ datetime.datetime(2002, 4, 3, 0, 0)
u'john@example.com' u'john@example.com'
>>> p = Person(**dict(valid_params, email=22)) >>> p = Person(**dict(valid_params, email=22))
>>> p.validate() >>> p.validate()['email']
{'email': [u'Enter a valid e-mail address.']} [u'Enter a valid e-mail address.']
# Make sure that Date and DateTime return validation errors and don't raise Python errors. # Make sure that Date and DateTime return validation errors and don't raise Python errors.
>>> Person(name='John Doe', is_child=True, email='abc@def.com').validate() >>> p = Person(name='John Doe', is_child=True, email='abc@def.com')
{'favorite_moment': [u'This field is required.'], 'birthdate': [u'This field is required.']} >>> errors = p.validate()
>>> errors['favorite_moment']
[u'This field is required.']
>>> errors['birthdate']
[u'This field is required.']
"""} """}

View File

@ -252,8 +252,8 @@ ValidationError: [u'This field is required.']
</select> </select>
<input type="text" name="field1_2_0" value="2007-04-25" id="id_field1_2_0" /><input type="text" name="field1_2_1" value="06:24:00" id="id_field1_2_1" /></td></tr> <input type="text" name="field1_2_0" value="2007-04-25" id="id_field1_2_0" /><input type="text" name="field1_2_1" value="06:24:00" id="id_field1_2_1" /></td></tr>
>>> f.cleaned_data >>> f.cleaned_data['field1']
{'field1': u'some text,JP,2007-04-25 06:24:00'} u'some text,JP,2007-04-25 06:24:00'
# IPAddressField ################################################################## # IPAddressField ##################################################################

View File

@ -36,8 +36,8 @@ True
u'' u''
>>> p.errors.as_text() >>> p.errors.as_text()
u'' u''
>>> p.cleaned_data >>> p.cleaned_data["first_name"], p.cleaned_data["last_name"], p.cleaned_data["birthday"]
{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)} (u'John', u'Lennon', datetime.date(1940, 10, 9))
>>> print p['first_name'] >>> print p['first_name']
<input type="text" name="first_name" value="John" id="id_first_name" /> <input type="text" name="first_name" value="John" id="id_first_name" />
>>> print p['last_name'] >>> print p['last_name']
@ -68,8 +68,12 @@ Empty dictionaries are valid, too.
>>> p = Person({}) >>> p = Person({})
>>> p.is_bound >>> p.is_bound
True True
>>> p.errors >>> p.errors['first_name']
{'first_name': [u'This field is required.'], 'last_name': [u'This field is required.'], 'birthday': [u'This field is required.']} [u'This field is required.']
>>> p.errors['last_name']
[u'This field is required.']
>>> p.errors['birthday']
[u'This field is required.']
>>> p.is_valid() >>> p.is_valid()
False False
>>> p.cleaned_data >>> p.cleaned_data
@ -137,8 +141,10 @@ u'<li><label for="id_first_name">First name:</label> <input type="text" name="fi
u'<p><label for="id_first_name">First name:</label> <input type="text" name="first_name" value="John" id="id_first_name" /></p>\n<p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" /></p>\n<p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></p>' u'<p><label for="id_first_name">First name:</label> <input type="text" name="first_name" value="John" id="id_first_name" /></p>\n<p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" /></p>\n<p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></p>'
>>> p = Person({'last_name': u'Lennon'}) >>> p = Person({'last_name': u'Lennon'})
>>> p.errors >>> p.errors['first_name']
{'first_name': [u'This field is required.'], 'birthday': [u'This field is required.']} [u'This field is required.']
>>> p.errors['birthday']
[u'This field is required.']
>>> p.is_valid() >>> p.is_valid()
False False
>>> p.errors.as_ul() >>> p.errors.as_ul()
@ -175,8 +181,13 @@ but cleaned_data contains only the form's fields.
>>> p = Person(data) >>> p = Person(data)
>>> p.is_valid() >>> p.is_valid()
True True
>>> p.cleaned_data >>> p.cleaned_data['first_name']
{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)} u'John'
>>> p.cleaned_data['last_name']
u'Lennon'
>>> p.cleaned_data['birthday']
datetime.date(1940, 10, 9)
cleaned_data will include a key and value for *all* fields defined in the Form, cleaned_data will include a key and value for *all* fields defined in the Form,
even if the Form's data didn't include a value for fields that are not even if the Form's data didn't include a value for fields that are not
@ -191,8 +202,12 @@ empty string.
>>> f = OptionalPersonForm(data) >>> f = OptionalPersonForm(data)
>>> f.is_valid() >>> f.is_valid()
True True
>>> f.cleaned_data >>> f.cleaned_data['nick_name']
{'nick_name': u'', 'first_name': u'John', 'last_name': u'Lennon'} u''
>>> f.cleaned_data['first_name']
u'John'
>>> f.cleaned_data['last_name']
u'Lennon'
For DateFields, it's set to None. For DateFields, it's set to None.
>>> class OptionalPersonForm(Form): >>> class OptionalPersonForm(Form):
@ -203,8 +218,12 @@ For DateFields, it's set to None.
>>> f = OptionalPersonForm(data) >>> f = OptionalPersonForm(data)
>>> f.is_valid() >>> f.is_valid()
True True
>>> f.cleaned_data >>> print f.cleaned_data['birth_date']
{'birth_date': None, 'first_name': u'John', 'last_name': u'Lennon'} None
>>> f.cleaned_data['first_name']
u'John'
>>> f.cleaned_data['last_name']
u'Lennon'
"auto_id" tells the Form to add an "id" attribute to each form element. "auto_id" tells the Form to add an "id" attribute to each form element.
If it's a string that contains '%s', Django will use that as a format string If it's a string that contains '%s', Django will use that as a format string
@ -549,18 +568,22 @@ The MultipleHiddenInput widget renders multiple values as hidden fields.
When using CheckboxSelectMultiple, the framework expects a list of input and When using CheckboxSelectMultiple, the framework expects a list of input and
returns a list of input. returns a list of input.
>>> f = SongForm({'name': 'Yesterday'}, auto_id=False) >>> f = SongForm({'name': 'Yesterday'}, auto_id=False)
>>> f.errors >>> f.errors['composers']
{'composers': [u'This field is required.']} [u'This field is required.']
>>> f = SongForm({'name': 'Yesterday', 'composers': ['J']}, auto_id=False) >>> f = SongForm({'name': 'Yesterday', 'composers': ['J']}, auto_id=False)
>>> f.errors >>> f.errors
{} {}
>>> f.cleaned_data >>> f.cleaned_data['composers']
{'composers': [u'J'], 'name': u'Yesterday'} [u'J']
>>> f.cleaned_data['name']
u'Yesterday'
>>> f = SongForm({'name': 'Yesterday', 'composers': ['J', 'P']}, auto_id=False) >>> f = SongForm({'name': 'Yesterday', 'composers': ['J', 'P']}, auto_id=False)
>>> f.errors >>> f.errors
{} {}
>>> f.cleaned_data >>> f.cleaned_data['composers']
{'composers': [u'J', u'P'], 'name': u'Yesterday'} [u'J', u'P']
>>> f.cleaned_data['name']
u'Yesterday'
Validation errors are HTML-escaped when output as HTML. Validation errors are HTML-escaped when output as HTML.
>>> class EscapingForm(Form): >>> class EscapingForm(Form):
@ -598,16 +621,24 @@ including the current field (e.g., the field XXX if you're in clean_XXX()).
>>> f.errors >>> f.errors
{} {}
>>> f = UserRegistration({}, auto_id=False) >>> f = UserRegistration({}, auto_id=False)
>>> f.errors >>> f.errors['username']
{'username': [u'This field is required.'], 'password1': [u'This field is required.'], 'password2': [u'This field is required.']} [u'This field is required.']
>>> f.errors['password1']
[u'This field is required.']
>>> f.errors['password2']
[u'This field is required.']
>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'}, auto_id=False) >>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)
>>> f.errors >>> f.errors['password2']
{'password2': [u'Please make sure your passwords match.']} [u'Please make sure your passwords match.']
>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False) >>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False)
>>> f.errors >>> f.errors
{} {}
>>> f.cleaned_data >>> f.cleaned_data['username']
{'username': u'adrian', 'password1': u'foo', 'password2': u'foo'} u'adrian'
>>> f.cleaned_data['password1']
u'foo'
>>> f.cleaned_data['password2']
u'foo'
Another way of doing multiple-field validation is by implementing the Another way of doing multiple-field validation is by implementing the
Form's clean() method. If you do this, any ValidationError raised by that Form's clean() method. If you do this, any ValidationError raised by that
@ -632,11 +663,15 @@ Form.clean() is required to return a dictionary of all clean data.
<tr><th>Username:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="username" maxlength="10" /></td></tr> <tr><th>Username:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="username" maxlength="10" /></td></tr>
<tr><th>Password1:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="password" name="password1" /></td></tr> <tr><th>Password1:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="password" name="password1" /></td></tr>
<tr><th>Password2:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="password" name="password2" /></td></tr> <tr><th>Password2:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="password" name="password2" /></td></tr>
>>> f.errors >>> f.errors['username']
{'username': [u'This field is required.'], 'password1': [u'This field is required.'], 'password2': [u'This field is required.']} [u'This field is required.']
>>> f.errors['password1']
[u'This field is required.']
>>> f.errors['password2']
[u'This field is required.']
>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'}, auto_id=False) >>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)
>>> f.errors >>> f.errors['__all__']
{'__all__': [u'Please make sure your passwords match.']} [u'Please make sure your passwords match.']
>>> print f.as_table() >>> print f.as_table()
<tr><td colspan="2"><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></td></tr> <tr><td colspan="2"><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></td></tr>
<tr><th>Username:</th><td><input type="text" name="username" value="adrian" maxlength="10" /></td></tr> <tr><th>Username:</th><td><input type="text" name="username" value="adrian" maxlength="10" /></td></tr>
@ -650,8 +685,12 @@ Form.clean() is required to return a dictionary of all clean data.
>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False) >>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False)
>>> f.errors >>> f.errors
{} {}
>>> f.cleaned_data >>> f.cleaned_data['username']
{'username': u'adrian', 'password1': u'foo', 'password2': u'foo'} u'adrian'
>>> f.cleaned_data['password1']
u'foo'
>>> f.cleaned_data['password2']
u'foo'
# Dynamic construction ######################################################## # Dynamic construction ########################################################
@ -1024,8 +1063,8 @@ An 'initial' value is *not* used as a fallback if data is not provided. In this
example, we don't provide a value for 'username', and the form raises a example, we don't provide a value for 'username', and the form raises a
validation error rather than using the initial value for 'username'. validation error rather than using the initial value for 'username'.
>>> p = UserRegistration({'password': 'secret'}) >>> p = UserRegistration({'password': 'secret'})
>>> p.errors >>> p.errors['username']
{'username': [u'This field is required.']} [u'This field is required.']
>>> p.is_valid() >>> p.is_valid()
False False
@ -1069,8 +1108,8 @@ A dynamic 'initial' value is *not* used as a fallback if data is not provided.
In this example, we don't provide a value for 'username', and the form raises a In this example, we don't provide a value for 'username', and the form raises a
validation error rather than using the initial value for 'username'. validation error rather than using the initial value for 'username'.
>>> p = UserRegistration({'password': 'secret'}, initial={'username': 'django'}) >>> p = UserRegistration({'password': 'secret'}, initial={'username': 'django'})
>>> p.errors >>> p.errors['username']
{'username': [u'This field is required.']} [u'This field is required.']
>>> p.is_valid() >>> p.is_valid()
False False
@ -1123,8 +1162,8 @@ A callable 'initial' value is *not* used as a fallback if data is not provided.
In this example, we don't provide a value for 'username', and the form raises a In this example, we don't provide a value for 'username', and the form raises a
validation error rather than using the initial value for 'username'. validation error rather than using the initial value for 'username'.
>>> p = UserRegistration({'password': 'secret'}, initial={'username': initial_django}) >>> p = UserRegistration({'password': 'secret'}, initial={'username': initial_django})
>>> p.errors >>> p.errors['username']
{'username': [u'This field is required.']} [u'This field is required.']
>>> p.is_valid() >>> p.is_valid()
False False
@ -1258,8 +1297,12 @@ actual field name.
{} {}
>>> p.is_valid() >>> p.is_valid()
True True
>>> p.cleaned_data >>> p.cleaned_data['first_name']
{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)} u'John'
>>> p.cleaned_data['last_name']
u'Lennon'
>>> p.cleaned_data['birthday']
datetime.date(1940, 10, 9)
Let's try submitting some bad data to make sure form.errors and field.errors Let's try submitting some bad data to make sure form.errors and field.errors
work as expected. work as expected.
@ -1269,8 +1312,12 @@ work as expected.
... 'person1-birthday': u'' ... 'person1-birthday': u''
... } ... }
>>> p = Person(data, prefix='person1') >>> p = Person(data, prefix='person1')
>>> p.errors >>> p.errors['first_name']
{'first_name': [u'This field is required.'], 'last_name': [u'This field is required.'], 'birthday': [u'This field is required.']} [u'This field is required.']
>>> p.errors['last_name']
[u'This field is required.']
>>> p.errors['birthday']
[u'This field is required.']
>>> p['first_name'].errors >>> p['first_name'].errors
[u'This field is required.'] [u'This field is required.']
>>> p['person1-first_name'].errors >>> p['person1-first_name'].errors
@ -1286,8 +1333,12 @@ the form doesn't "see" the fields.
... 'birthday': u'1940-10-9' ... 'birthday': u'1940-10-9'
... } ... }
>>> p = Person(data, prefix='person1') >>> p = Person(data, prefix='person1')
>>> p.errors >>> p.errors['first_name']
{'first_name': [u'This field is required.'], 'last_name': [u'This field is required.'], 'birthday': [u'This field is required.']} [u'This field is required.']
>>> p.errors['last_name']
[u'This field is required.']
>>> p.errors['birthday']
[u'This field is required.']
With prefixes, a single data dictionary can hold data for multiple instances With prefixes, a single data dictionary can hold data for multiple instances
of the same form. of the same form.
@ -1302,13 +1353,21 @@ of the same form.
>>> p1 = Person(data, prefix='person1') >>> p1 = Person(data, prefix='person1')
>>> p1.is_valid() >>> p1.is_valid()
True True
>>> p1.cleaned_data >>> p1.cleaned_data['first_name']
{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)} u'John'
>>> p1.cleaned_data['last_name']
u'Lennon'
>>> p1.cleaned_data['birthday']
datetime.date(1940, 10, 9)
>>> p2 = Person(data, prefix='person2') >>> p2 = Person(data, prefix='person2')
>>> p2.is_valid() >>> p2.is_valid()
True True
>>> p2.cleaned_data >>> p2.cleaned_data['first_name']
{'first_name': u'Jim', 'last_name': u'Morrison', 'birthday': datetime.date(1943, 12, 8)} u'Jim'
>>> p2.cleaned_data['last_name']
u'Morrison'
>>> p2.cleaned_data['birthday']
datetime.date(1943, 12, 8)
By default, forms append a hyphen between the prefix and the field name, but a By default, forms append a hyphen between the prefix and the field name, but a
form can alter that behavior by implementing the add_prefix() method. This form can alter that behavior by implementing the add_prefix() method. This
@ -1333,8 +1392,12 @@ self.prefix.
>>> p = Person(data, prefix='foo') >>> p = Person(data, prefix='foo')
>>> p.is_valid() >>> p.is_valid()
True True
>>> p.cleaned_data >>> p.cleaned_data['first_name']
{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)} u'John'
>>> p.cleaned_data['last_name']
u'Lennon'
>>> p.cleaned_data['birthday']
datetime.date(1940, 10, 9)
# Forms with NullBooleanFields ################################################ # Forms with NullBooleanFields ################################################