Fixed #11404. Added ``FormSet.has_changed``, for consistancy with ``Form.has_changed``. Thanks to michelts for the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16773 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Alex Gaynor 2011-09-10 02:42:05 +00:00
parent 01b0eb50fd
commit d14bf8c62b
3 changed files with 48 additions and 1 deletions

View File

@ -300,6 +300,12 @@ class BaseFormSet(StrAndUnicode):
"""
pass
def has_changed(self):
"""
Returns true if data in any form differs from initial.
"""
return any(form.has_changed() for form in self)
def add_fields(self, form, index):
"""A hook for adding extra fields on to each form instance."""
if self.can_order:

View File

@ -150,6 +150,20 @@ As we can see, ``formset.errors`` is a list whose entries correspond to the
forms in the formset. Validation was performed for each of the two forms, and
the expected error message appears for the second item.
We can also check if form data differs from the initial data (i.e. the form was
sent without any data)::
>>> data = {
... 'form-TOTAL_FORMS': u'1',
... 'form-INITIAL_FORMS': u'0',
... 'form-MAX_NUM_FORMS': u'',
... 'form-0-title': u'',
... 'form-0-pub_date': u'',
... }
>>> formset = ArticleFormSet(data)
>>> formset.has_changed()
False
.. _understanding-the-managementform:
Understanding the ManagementForm

View File

@ -73,9 +73,11 @@ class FormsFormsetTestCase(TestCase):
self.assertTrue(formset.is_valid())
self.assertEqual([form.cleaned_data for form in formset.forms], [{'votes': 100, 'choice': u'Calexico'}])
# If a FormSet was not passed any data, its is_valid method should return False.
# If a FormSet was not passed any data, its is_valid and has_changed
# methods should return False.
formset = ChoiceFormSet()
self.assertFalse(formset.is_valid())
self.assertFalse(formset.has_changed())
def test_formset_validation(self):
# FormSet instances can also have an error attribute if validation failed for
@ -93,6 +95,31 @@ class FormsFormsetTestCase(TestCase):
self.assertFalse(formset.is_valid())
self.assertEqual(formset.errors, [{'votes': [u'This field is required.']}])
def test_formset_has_changed(self):
# FormSet instances has_changed method will be True if any data is
# passed to his forms, even if the formset didn't validate
data = {
'choices-TOTAL_FORMS': '1', # the number of forms rendered
'choices-INITIAL_FORMS': '0', # the number of forms with initial data
'choices-MAX_NUM_FORMS': '0', # max number of forms
'choices-0-choice': '',
'choices-0-votes': '',
}
blank_formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
self.assertFalse(blank_formset.has_changed())
# invalid formset test
data['choices-0-choice'] = 'Calexico'
invalid_formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
self.assertFalse(invalid_formset.is_valid())
self.assertTrue(invalid_formset.has_changed())
# valid formset test
data['choices-0-votes'] = '100'
valid_formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
self.assertTrue(valid_formset.is_valid())
self.assertTrue(valid_formset.has_changed())
def test_formset_initial_data(self):
# We can also prefill a FormSet with existing data by providing an ``initial``
# argument to the constructor. ``initial`` should be a list of dicts. By default,