Ticket #5524: 5524-new-3.diff
File 5524-new-3.diff, 12.5 KB (added by , 13 years ago) |
---|
-
docs/releases/1.4.txt
854 854 If you are using PUT or DELETE methods in AJAX applications, please see the 855 855 :ref:`instructions about using AJAX and CSRF <csrf-ajax>`. 856 856 857 `cleaned_data` dictionary kept for invalid forms 858 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 859 860 The :attr:`~django.forms.Form.cleaned_data` dictionary is now always present 861 after form validation. When the form doesn't validate, it contains only the 862 fields that passed validation. You should test the success of the validation 863 with the :meth:`~django.forms.Form.is_valid()` method and not with the 864 presence or absence of the :attr:`~django.forms.Form.cleaned_data` attribute 865 on the form. 866 857 867 ``django.core.template_loaders`` 858 868 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 859 869 -
docs/ref/forms/api.txt
199 199 always cleans the input into a Unicode string. We'll cover the encoding 200 200 implications later in this document. 201 201 202 If your data does *not* validate, your ``Form`` instance will not have a203 ``cleaned_data`` attribute::202 If your data does *not* validate, the ``cleaned_data`` dictionary contains 203 only the valid fields:: 204 204 205 205 >>> data = {'subject': '', 206 206 ... 'message': 'Hi there', … … 210 210 >>> f.is_valid() 211 211 False 212 212 >>> f.cleaned_data 213 Traceback (most recent call last): 214 ... 215 AttributeError: 'ContactForm' object has no attribute 'cleaned_data' 213 {'cc_myself': True, 'message': u'Hi there'} 216 214 215 .. versionchanged:: 1.4 216 217 Until Django 1.4, the ``cleaned_data`` attribute wasn't defined at all when 218 the ``Form`` didn't validate. 219 217 220 ``cleaned_data`` will always *only* contain a key for fields defined in the 218 221 ``Form``, even if you pass extra data when you define the ``Form``. In this 219 222 example, we pass a bunch of extra fields to the ``ContactForm`` constructor, … … 232 235 >>> f.cleaned_data # Doesn't contain extra_field_1, etc. 233 236 {'cc_myself': True, 'message': u'Hi there', 'sender': u'foo@example.com', 'subject': u'hello'} 234 237 235 ``cleaned_data`` will include a key and value for *all* fields defined in the 236 ``Form``, even if the data didn't include a value for fields that are not 237 required. In this example, the data dictionary doesn't include a value for the238 When the ``Form`` is valid, ``cleaned_data`` will include a key and value for 239 *all* its fields, even if the data didn't include a value for some optional 240 fields. In this example, the data dictionary doesn't include a value for the 238 241 ``nick_name`` field, but ``cleaned_data`` includes it, with an empty value:: 239 242 240 243 >>> class OptionalPersonForm(Form): … … 585 588 586 589 Used to display HTML or access attributes for a single field of a 587 590 :class:`Form` instance. 588 591 589 592 The :meth:`__unicode__` and :meth:`__str__` methods of this object displays 590 593 the HTML for this field. 591 594 -
docs/ref/forms/validation.txt
360 360 considering aren't valid, we must remember to remove them from the 361 361 ``cleaned_data``. 362 362 363 In fact, Django will currently completely wipe out the ``cleaned_data`` 364 dictionary if there are any errors in the form. However, this behavior may 365 change in the future, so it's not a bad idea to clean up after yourself in the 366 first place. 363 .. versionchanged:: 1.4 364 365 Django used to remove the ``cleaned_data`` attribute entirely if there were 366 any errors in the form. Since version 1.4, ``cleaned_data`` is present even if 367 the form doesn't validate, but it contains only field values that did 368 validate. -
django/forms/models.py
497 497 all_unique_checks = set() 498 498 all_date_checks = set() 499 499 for form in self.forms: 500 if not hasattr(form, 'cleaned_data'):500 if not form.is_valid(): 501 501 continue 502 502 exclude = form._get_validation_exclusions() 503 503 unique_checks, date_checks = form.instance._get_unique_checks(exclude=exclude) … … 509 509 for uclass, unique_check in all_unique_checks: 510 510 seen_data = set() 511 511 for form in self.forms: 512 # if the form doesn't have cleaned_data then we ignore it, 513 # it's already invalid 514 if not hasattr(form, "cleaned_data"): 512 if not form.is_valid(): 515 513 continue 516 514 # get data for each field of each of unique_check 517 515 row_data = tuple([form.cleaned_data[field] for field in unique_check if field in form.cleaned_data]) 518 516 if row_data and not None in row_data: 519 # if we've a ready seen it then we have a uniqueness failure517 # if we've already seen it then we have a uniqueness failure 520 518 if row_data in seen_data: 521 519 # poke error messages into the right places and mark 522 520 # the form as invalid 523 521 errors.append(self.get_unique_error_message(unique_check)) 524 522 form._errors[NON_FIELD_ERRORS] = self.error_class([self.get_form_error()]) 525 del form.cleaned_data 526 break 523 # remove the data from the cleaned_data dict since it was invalid 524 for field in unique_check: 525 if field in form.cleaned_data: 526 del form.cleaned_data[field] 527 527 # mark the data as seen 528 528 seen_data.add(row_data) 529 529 # iterate over each of the date checks now … … 531 531 seen_data = set() 532 532 uclass, lookup, field, unique_for = date_check 533 533 for form in self.forms: 534 # if the form doesn't have cleaned_data then we ignore it, 535 # it's already invalid 536 if not hasattr(self, 'cleaned_data'): 534 if not form.is_valid(): 537 535 continue 538 536 # see if we have data for both fields 539 537 if (form.cleaned_data and form.cleaned_data[field] is not None … … 547 545 else: 548 546 date_data = (getattr(form.cleaned_data[unique_for], lookup),) 549 547 data = (form.cleaned_data[field],) + date_data 550 # if we've a ready seen it then we have a uniqueness failure548 # if we've already seen it then we have a uniqueness failure 551 549 if data in seen_data: 552 550 # poke error messages into the right places and mark 553 551 # the form as invalid 554 552 errors.append(self.get_date_error_message(date_check)) 555 553 form._errors[NON_FIELD_ERRORS] = self.error_class([self.get_form_error()]) 556 del form.cleaned_data 557 break 554 # remove the data from the cleaned_data dict since it was invalid 555 del form.cleaned_data[field] 556 # mark the data as seen 558 557 seen_data.add(data) 559 558 if errors: 560 559 raise ValidationError(errors) -
django/forms/forms.py
270 270 self._clean_fields() 271 271 self._clean_form() 272 272 self._post_clean() 273 if self._errors:274 del self.cleaned_data275 273 276 274 def _clean_fields(self): 277 275 for name, field in self.fields.items(): -
django/contrib/formtools/tests/__init__.py
362 362 363 363 class WizardWithProcessStep(TestWizardClass): 364 364 def process_step(self, request, form, step): 365 that.assertTrue( hasattr(form, 'cleaned_data'))365 that.assertTrue(form.is_valid()) 366 366 reached[0] = True 367 367 368 368 wizard = WizardWithProcessStep([WizardPageOneForm, -
tests/modeltests/model_forms/tests.py
637 637 f = BaseCategoryForm({'name': '', 'slug': 'not a slug!', 'url': 'foo'}) 638 638 self.assertEqual(f.errors['name'], [u'This field is required.']) 639 639 self.assertEqual(f.errors['slug'], [u"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."]) 640 with self.assertRaises(AttributeError): 641 f.cleaned_data 640 self.assertEqual(f.cleaned_data, {'url': u'foo'}) 642 641 with self.assertRaises(ValueError): 643 642 f.save() 644 643 f = BaseCategoryForm({'name': '', 'slug': '', 'url': 'foo'}) -
tests/regressiontests/forms/tests/forms.py
79 79 self.assertEqual(p.errors['last_name'], [u'This field is required.']) 80 80 self.assertEqual(p.errors['birthday'], [u'This field is required.']) 81 81 self.assertFalse(p.is_valid()) 82 try: 83 p.cleaned_data 84 self.fail('Attempts to access cleaned_data when validation fails should fail.') 85 except AttributeError: 86 pass 82 self.assertEqual(p.cleaned_data, {}) 87 83 self.assertEqual(str(p), """<tr><th><label for="id_first_name">First name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="first_name" id="id_first_name" /></td></tr> 88 84 <tr><th><label for="id_last_name">Last name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="last_name" id="id_last_name" /></td></tr> 89 85 <tr><th><label for="id_birthday">Birthday:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="birthday" id="id_birthday" /></td></tr>""") … … 142 138 * This field is required. 143 139 * birthday 144 140 * This field is required.""") 145 try: 146 p.cleaned_data 147 self.fail('Attempts to access cleaned_data when validation fails should fail.') 148 except AttributeError: 149 pass 141 self.assertEqual(p.cleaned_data, {'last_name': u'Lennon'}) 150 142 self.assertEqual(p['first_name'].errors, [u'This field is required.']) 151 143 self.assertEqual(p['first_name'].errors.as_ul(), u'<ul class="errorlist"><li>This field is required.</li></ul>') 152 144 self.assertEqual(p['first_name'].errors.as_text(), u'* This field is required.') … … 1672 1664 form = SongForm(data, empty_permitted=False) 1673 1665 self.assertFalse(form.is_valid()) 1674 1666 self.assertEqual(form.errors, {'name': [u'This field is required.'], 'artist': [u'This field is required.']}) 1675 try: 1676 form.cleaned_data 1677 self.fail('Attempts to access cleaned_data when validation fails should fail.') 1678 except AttributeError: 1679 pass 1667 self.assertEqual(form.cleaned_data, {}) 1680 1668 1681 1669 # Now let's show what happens when empty_permitted=True and the form is empty. 1682 1670 form = SongForm(data, empty_permitted=True) … … 1690 1678 form = SongForm(data, empty_permitted=False) 1691 1679 self.assertFalse(form.is_valid()) 1692 1680 self.assertEqual(form.errors, {'name': [u'This field is required.']}) 1693 try: 1694 form.cleaned_data 1695 self.fail('Attempts to access cleaned_data when validation fails should fail.') 1696 except AttributeError: 1697 pass 1681 self.assertEqual(form.cleaned_data, {'artist': u'The Doors'}) 1698 1682 1699 1683 # If a field is not given in the data then None is returned for its data. Lets 1700 1684 # make sure that when checking for empty_permitted that None is treated