summaryrefslogtreecommitdiff
path: root/tests/regressiontests/forms/formsets.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/regressiontests/forms/formsets.py')
-rw-r--r--tests/regressiontests/forms/formsets.py762
1 files changed, 0 insertions, 762 deletions
diff --git a/tests/regressiontests/forms/formsets.py b/tests/regressiontests/forms/formsets.py
deleted file mode 100644
index f8b8ae2a8a..0000000000
--- a/tests/regressiontests/forms/formsets.py
+++ /dev/null
@@ -1,762 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.test.testcases import TestCase
-from django.forms.forms import Form
-from django.forms.fields import CharField, IntegerField
-from django.forms.formsets import formset_factory
-tests = """
-# Basic FormSet creation and usage ############################################
-
-FormSet allows us to use multiple instance of the same form on 1 page. For now,
-the best way to create a FormSet is by using the formset_factory function.
-
->>> from django.forms import Form, CharField, IntegerField, ValidationError
->>> from django.forms.formsets import formset_factory, BaseFormSet
-
->>> class Choice(Form):
-... choice = CharField()
-... votes = IntegerField()
-
->>> ChoiceFormSet = formset_factory(Choice)
-
-A FormSet constructor takes the same arguments as Form. Let's create a FormSet
-for adding data. By default, it displays 1 blank form. It can display more,
-but we'll look at how to do so later.
-
->>> formset = ChoiceFormSet(auto_id=False, prefix='choices')
->>> print formset
-<input type="hidden" name="choices-TOTAL_FORMS" value="1" /><input type="hidden" name="choices-INITIAL_FORMS" value="0" /><input type="hidden" name="choices-MAX_NUM_FORMS" />
-<tr><th>Choice:</th><td><input type="text" name="choices-0-choice" /></td></tr>
-<tr><th>Votes:</th><td><input type="text" name="choices-0-votes" /></td></tr>
-
-
-On thing to note is that there needs to be a special value in the data. This
-value tells the FormSet how many forms were displayed so it can tell how
-many forms it needs to clean and validate. You could use javascript to create
-new forms on the client side, but they won't get validated unless you increment
-the TOTAL_FORMS field appropriately.
-
->>> 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': 'Calexico',
-... 'choices-0-votes': '100',
-... }
-
-We treat FormSet pretty much like we would treat a normal Form. FormSet has an
-is_valid method, and a cleaned_data or errors attribute depending on whether all
-the forms passed validation. However, unlike a Form instance, cleaned_data and
-errors will be a list of dicts rather than just a single dict.
-
->>> formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
->>> formset.is_valid()
-True
->>> [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.
->>> formset = ChoiceFormSet()
->>> formset.is_valid()
-False
-
-FormSet instances can also have an error attribute if validation failed for
-any of the forms.
-
->>> 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': 'Calexico',
-... 'choices-0-votes': '',
-... }
-
->>> formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
->>> formset.is_valid()
-False
->>> formset.errors
-[{'votes': [u'This field is required.']}]
-
-
-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,
-an extra blank form is included.
-
->>> initial = [{'choice': u'Calexico', 'votes': 100}]
->>> formset = ChoiceFormSet(initial=initial, auto_id=False, prefix='choices')
->>> for form in formset.forms:
-... print form.as_ul()
-<li>Choice: <input type="text" name="choices-0-choice" value="Calexico" /></li>
-<li>Votes: <input type="text" name="choices-0-votes" value="100" /></li>
-<li>Choice: <input type="text" name="choices-1-choice" /></li>
-<li>Votes: <input type="text" name="choices-1-votes" /></li>
-
-
-Let's simulate what would happen if we submitted this form.
-
->>> data = {
-... 'choices-TOTAL_FORMS': '2', # the number of forms rendered
-... 'choices-INITIAL_FORMS': '1', # the number of forms with initial data
-... 'choices-MAX_NUM_FORMS': '0', # max number of forms
-... 'choices-0-choice': 'Calexico',
-... 'choices-0-votes': '100',
-... 'choices-1-choice': '',
-... 'choices-1-votes': '',
-... }
-
->>> formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
->>> formset.is_valid()
-True
->>> [form.cleaned_data for form in formset.forms]
-[{'votes': 100, 'choice': u'Calexico'}, {}]
-
-But the second form was blank! Shouldn't we get some errors? No. If we display
-a form as blank, it's ok for it to be submitted as blank. If we fill out even
-one of the fields of a blank form though, it will be validated. We may want to
-required that at least x number of forms are completed, but we'll show how to
-handle that later.
-
->>> data = {
-... 'choices-TOTAL_FORMS': '2', # the number of forms rendered
-... 'choices-INITIAL_FORMS': '1', # the number of forms with initial data
-... 'choices-MAX_NUM_FORMS': '0', # max number of forms
-... 'choices-0-choice': 'Calexico',
-... 'choices-0-votes': '100',
-... 'choices-1-choice': 'The Decemberists',
-... 'choices-1-votes': '', # missing value
-... }
-
->>> formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
->>> formset.is_valid()
-False
->>> formset.errors
-[{}, {'votes': [u'This field is required.']}]
-
-If we delete data that was pre-filled, we should get an error. Simply removing
-data from form fields isn't the proper way to delete it. We'll see how to
-handle that case later.
-
->>> data = {
-... 'choices-TOTAL_FORMS': '2', # the number of forms rendered
-... 'choices-INITIAL_FORMS': '1', # the number of forms with initial data
-... 'choices-MAX_NUM_FORMS': '0', # max number of forms
-... 'choices-0-choice': '', # deleted value
-... 'choices-0-votes': '', # deleted value
-... 'choices-1-choice': '',
-... 'choices-1-votes': '',
-... }
-
->>> formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
->>> formset.is_valid()
-False
->>> formset.errors
-[{'votes': [u'This field is required.'], 'choice': [u'This field is required.']}, {}]
-
-
-# Displaying more than 1 blank form ###########################################
-
-We can also display more than 1 empty form at a time. To do so, pass a
-extra argument to formset_factory.
-
->>> ChoiceFormSet = formset_factory(Choice, extra=3)
-
->>> formset = ChoiceFormSet(auto_id=False, prefix='choices')
->>> for form in formset.forms:
-... print form.as_ul()
-<li>Choice: <input type="text" name="choices-0-choice" /></li>
-<li>Votes: <input type="text" name="choices-0-votes" /></li>
-<li>Choice: <input type="text" name="choices-1-choice" /></li>
-<li>Votes: <input type="text" name="choices-1-votes" /></li>
-<li>Choice: <input type="text" name="choices-2-choice" /></li>
-<li>Votes: <input type="text" name="choices-2-votes" /></li>
-
-Since we displayed every form as blank, we will also accept them back as blank.
-This may seem a little strange, but later we will show how to require a minimum
-number of forms to be completed.
-
->>> data = {
-... 'choices-TOTAL_FORMS': '3', # 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': '',
-... 'choices-1-choice': '',
-... 'choices-1-votes': '',
-... 'choices-2-choice': '',
-... 'choices-2-votes': '',
-... }
-
->>> formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
->>> formset.is_valid()
-True
->>> [form.cleaned_data for form in formset.forms]
-[{}, {}, {}]
-
-
-We can just fill out one of the forms.
-
->>> data = {
-... 'choices-TOTAL_FORMS': '3', # 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': 'Calexico',
-... 'choices-0-votes': '100',
-... 'choices-1-choice': '',
-... 'choices-1-votes': '',
-... 'choices-2-choice': '',
-... 'choices-2-votes': '',
-... }
-
->>> formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
->>> formset.is_valid()
-True
->>> [form.cleaned_data for form in formset.forms]
-[{'votes': 100, 'choice': u'Calexico'}, {}, {}]
-
-
-And once again, if we try to partially complete a form, validation will fail.
-
->>> data = {
-... 'choices-TOTAL_FORMS': '3', # 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': 'Calexico',
-... 'choices-0-votes': '100',
-... 'choices-1-choice': 'The Decemberists',
-... 'choices-1-votes': '', # missing value
-... 'choices-2-choice': '',
-... 'choices-2-votes': '',
-... }
-
->>> formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
->>> formset.is_valid()
-False
->>> formset.errors
-[{}, {'votes': [u'This field is required.']}, {}]
-
-
-The extra argument also works when the formset is pre-filled with initial
-data.
-
->>> initial = [{'choice': u'Calexico', 'votes': 100}]
->>> formset = ChoiceFormSet(initial=initial, auto_id=False, prefix='choices')
->>> for form in formset.forms:
-... print form.as_ul()
-<li>Choice: <input type="text" name="choices-0-choice" value="Calexico" /></li>
-<li>Votes: <input type="text" name="choices-0-votes" value="100" /></li>
-<li>Choice: <input type="text" name="choices-1-choice" /></li>
-<li>Votes: <input type="text" name="choices-1-votes" /></li>
-<li>Choice: <input type="text" name="choices-2-choice" /></li>
-<li>Votes: <input type="text" name="choices-2-votes" /></li>
-<li>Choice: <input type="text" name="choices-3-choice" /></li>
-<li>Votes: <input type="text" name="choices-3-votes" /></li>
-
-Make sure retrieving an empty form works, and it shows up in the form list
-
->>> formset.empty_form.empty_permitted
-True
->>> print formset.empty_form.as_ul()
-<li>Choice: <input type="text" name="choices-__prefix__-choice" /></li>
-<li>Votes: <input type="text" name="choices-__prefix__-votes" /></li>
-
-# FormSets with deletion ######################################################
-
-We can easily add deletion ability to a FormSet with an argument to
-formset_factory. This will add a boolean field to each form instance. When
-that boolean field is True, the form will be in formset.deleted_forms
-
->>> ChoiceFormSet = formset_factory(Choice, can_delete=True)
-
->>> initial = [{'choice': u'Calexico', 'votes': 100}, {'choice': u'Fergie', 'votes': 900}]
->>> formset = ChoiceFormSet(initial=initial, auto_id=False, prefix='choices')
->>> for form in formset.forms:
-... print form.as_ul()
-<li>Choice: <input type="text" name="choices-0-choice" value="Calexico" /></li>
-<li>Votes: <input type="text" name="choices-0-votes" value="100" /></li>
-<li>Delete: <input type="checkbox" name="choices-0-DELETE" /></li>
-<li>Choice: <input type="text" name="choices-1-choice" value="Fergie" /></li>
-<li>Votes: <input type="text" name="choices-1-votes" value="900" /></li>
-<li>Delete: <input type="checkbox" name="choices-1-DELETE" /></li>
-<li>Choice: <input type="text" name="choices-2-choice" /></li>
-<li>Votes: <input type="text" name="choices-2-votes" /></li>
-<li>Delete: <input type="checkbox" name="choices-2-DELETE" /></li>
-
-To delete something, we just need to set that form's special delete field to
-'on'. Let's go ahead and delete Fergie.
-
->>> data = {
-... 'choices-TOTAL_FORMS': '3', # the number of forms rendered
-... 'choices-INITIAL_FORMS': '2', # the number of forms with initial data
-... 'choices-MAX_NUM_FORMS': '0', # max number of forms
-... 'choices-0-choice': 'Calexico',
-... 'choices-0-votes': '100',
-... 'choices-0-DELETE': '',
-... 'choices-1-choice': 'Fergie',
-... 'choices-1-votes': '900',
-... 'choices-1-DELETE': 'on',
-... 'choices-2-choice': '',
-... 'choices-2-votes': '',
-... 'choices-2-DELETE': '',
-... }
-
->>> formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
->>> formset.is_valid()
-True
->>> [form.cleaned_data for form in formset.forms]
-[{'votes': 100, 'DELETE': False, 'choice': u'Calexico'}, {'votes': 900, 'DELETE': True, 'choice': u'Fergie'}, {}]
->>> [form.cleaned_data for form in formset.deleted_forms]
-[{'votes': 900, 'DELETE': True, 'choice': u'Fergie'}]
-
-If we fill a form with something and then we check the can_delete checkbox for
-that form, that form's errors should not make the entire formset invalid since
-it's going to be deleted.
-
->>> class CheckForm(Form):
-... field = IntegerField(min_value=100)
-
->>> data = {
-... 'check-TOTAL_FORMS': '3', # the number of forms rendered
-... 'check-INITIAL_FORMS': '2', # the number of forms with initial data
-... 'check-MAX_NUM_FORMS': '0', # max number of forms
-... 'check-0-field': '200',
-... 'check-0-DELETE': '',
-... 'check-1-field': '50',
-... 'check-1-DELETE': 'on',
-... 'check-2-field': '',
-... 'check-2-DELETE': '',
-... }
->>> CheckFormSet = formset_factory(CheckForm, can_delete=True)
->>> formset = CheckFormSet(data, prefix='check')
->>> formset.is_valid()
-True
-
-If we remove the deletion flag now we will have our validation back.
-
->>> data['check-1-DELETE'] = ''
->>> formset = CheckFormSet(data, prefix='check')
->>> formset.is_valid()
-False
-
-Should be able to get deleted_forms from a valid formset even if a
-deleted form would have been invalid.
-
->>> class Person(Form):
-... name = CharField()
-
->>> PeopleForm = formset_factory(
-... form=Person,
-... can_delete=True)
-
->>> p = PeopleForm(
-... {'form-0-name': u'', 'form-0-DELETE': u'on', # no name!
-... 'form-TOTAL_FORMS': 1, 'form-INITIAL_FORMS': 1,
-... 'form-MAX_NUM_FORMS': 1})
-
->>> p.is_valid()
-True
->>> len(p.deleted_forms)
-1
-
-# FormSets with ordering ######################################################
-
-We can also add ordering ability to a FormSet with an agrument to
-formset_factory. This will add a integer field to each form instance. When
-form validation succeeds, [form.cleaned_data for form in formset.forms] will have the data in the correct
-order specified by the ordering fields. If a number is duplicated in the set
-of ordering fields, for instance form 0 and form 3 are both marked as 1, then
-the form index used as a secondary ordering criteria. In order to put
-something at the front of the list, you'd need to set it's order to 0.
-
->>> ChoiceFormSet = formset_factory(Choice, can_order=True)
-
->>> initial = [{'choice': u'Calexico', 'votes': 100}, {'choice': u'Fergie', 'votes': 900}]
->>> formset = ChoiceFormSet(initial=initial, auto_id=False, prefix='choices')
->>> for form in formset.forms:
-... print form.as_ul()
-<li>Choice: <input type="text" name="choices-0-choice" value="Calexico" /></li>
-<li>Votes: <input type="text" name="choices-0-votes" value="100" /></li>
-<li>Order: <input type="text" name="choices-0-ORDER" value="1" /></li>
-<li>Choice: <input type="text" name="choices-1-choice" value="Fergie" /></li>
-<li>Votes: <input type="text" name="choices-1-votes" value="900" /></li>
-<li>Order: <input type="text" name="choices-1-ORDER" value="2" /></li>
-<li>Choice: <input type="text" name="choices-2-choice" /></li>
-<li>Votes: <input type="text" name="choices-2-votes" /></li>
-<li>Order: <input type="text" name="choices-2-ORDER" /></li>
-
->>> data = {
-... 'choices-TOTAL_FORMS': '3', # the number of forms rendered
-... 'choices-INITIAL_FORMS': '2', # the number of forms with initial data
-... 'choices-MAX_NUM_FORMS': '0', # max number of forms
-... 'choices-0-choice': 'Calexico',
-... 'choices-0-votes': '100',
-... 'choices-0-ORDER': '1',
-... 'choices-1-choice': 'Fergie',
-... 'choices-1-votes': '900',
-... 'choices-1-ORDER': '2',
-... 'choices-2-choice': 'The Decemberists',
-... 'choices-2-votes': '500',
-... 'choices-2-ORDER': '0',
-... }
-
->>> formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
->>> formset.is_valid()
-True
->>> for form in formset.ordered_forms:
-... print form.cleaned_data
-{'votes': 500, 'ORDER': 0, 'choice': u'The Decemberists'}
-{'votes': 100, 'ORDER': 1, 'choice': u'Calexico'}
-{'votes': 900, 'ORDER': 2, 'choice': u'Fergie'}
-
-Ordering fields are allowed to be left blank, and if they *are* left blank,
-they will be sorted below everything else.
-
->>> data = {
-... 'choices-TOTAL_FORMS': '4', # the number of forms rendered
-... 'choices-INITIAL_FORMS': '3', # the number of forms with initial data
-... 'choices-MAX_NUM_FORMS': '0', # max number of forms
-... 'choices-0-choice': 'Calexico',
-... 'choices-0-votes': '100',
-... 'choices-0-ORDER': '1',
-... 'choices-1-choice': 'Fergie',
-... 'choices-1-votes': '900',
-... 'choices-1-ORDER': '2',
-... 'choices-2-choice': 'The Decemberists',
-... 'choices-2-votes': '500',
-... 'choices-2-ORDER': '',
-... 'choices-3-choice': 'Basia Bulat',
-... 'choices-3-votes': '50',
-... 'choices-3-ORDER': '',
-... }
-
->>> formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
->>> formset.is_valid()
-True
->>> for form in formset.ordered_forms:
-... print form.cleaned_data
-{'votes': 100, 'ORDER': 1, 'choice': u'Calexico'}
-{'votes': 900, 'ORDER': 2, 'choice': u'Fergie'}
-{'votes': 500, 'ORDER': None, 'choice': u'The Decemberists'}
-{'votes': 50, 'ORDER': None, 'choice': u'Basia Bulat'}
-
-Ordering should work with blank fieldsets.
-
->>> data = {
-... 'choices-TOTAL_FORMS': '3', # 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
-... }
-
->>> formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
->>> formset.is_valid()
-True
->>> for form in formset.ordered_forms:
-... print form.cleaned_data
-
-# FormSets with ordering + deletion ###########################################
-
-Let's try throwing ordering and deletion into the same form.
-
->>> ChoiceFormSet = formset_factory(Choice, can_order=True, can_delete=True)
-
->>> initial = [
-... {'choice': u'Calexico', 'votes': 100},
-... {'choice': u'Fergie', 'votes': 900},
-... {'choice': u'The Decemberists', 'votes': 500},
-... ]
->>> formset = ChoiceFormSet(initial=initial, auto_id=False, prefix='choices')
->>> for form in formset.forms:
-... print form.as_ul()
-<li>Choice: <input type="text" name="choices-0-choice" value="Calexico" /></li>
-<li>Votes: <input type="text" name="choices-0-votes" value="100" /></li>
-<li>Order: <input type="text" name="choices-0-ORDER" value="1" /></li>
-<li>Delete: <input type="checkbox" name="choices-0-DELETE" /></li>
-<li>Choice: <input type="text" name="choices-1-choice" value="Fergie" /></li>
-<li>Votes: <input type="text" name="choices-1-votes" value="900" /></li>
-<li>Order: <input type="text" name="choices-1-ORDER" value="2" /></li>
-<li>Delete: <input type="checkbox" name="choices-1-DELETE" /></li>
-<li>Choice: <input type="text" name="choices-2-choice" value="The Decemberists" /></li>
-<li>Votes: <input type="text" name="choices-2-votes" value="500" /></li>
-<li>Order: <input type="text" name="choices-2-ORDER" value="3" /></li>
-<li>Delete: <input type="checkbox" name="choices-2-DELETE" /></li>
-<li>Choice: <input type="text" name="choices-3-choice" /></li>
-<li>Votes: <input type="text" name="choices-3-votes" /></li>
-<li>Order: <input type="text" name="choices-3-ORDER" /></li>
-<li>Delete: <input type="checkbox" name="choices-3-DELETE" /></li>
-
-Let's delete Fergie, and put The Decemberists ahead of Calexico.
-
->>> data = {
-... 'choices-TOTAL_FORMS': '4', # the number of forms rendered
-... 'choices-INITIAL_FORMS': '3', # the number of forms with initial data
-... 'choices-MAX_NUM_FORMS': '0', # max number of forms
-... 'choices-0-choice': 'Calexico',
-... 'choices-0-votes': '100',
-... 'choices-0-ORDER': '1',
-... 'choices-0-DELETE': '',
-... 'choices-1-choice': 'Fergie',
-... 'choices-1-votes': '900',
-... 'choices-1-ORDER': '2',
-... 'choices-1-DELETE': 'on',
-... 'choices-2-choice': 'The Decemberists',
-... 'choices-2-votes': '500',
-... 'choices-2-ORDER': '0',
-... 'choices-2-DELETE': '',
-... 'choices-3-choice': '',
-... 'choices-3-votes': '',
-... 'choices-3-ORDER': '',
-... 'choices-3-DELETE': '',
-... }
-
->>> formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
->>> formset.is_valid()
-True
->>> for form in formset.ordered_forms:
-... print form.cleaned_data
-{'votes': 500, 'DELETE': False, 'ORDER': 0, 'choice': u'The Decemberists'}
-{'votes': 100, 'DELETE': False, 'ORDER': 1, 'choice': u'Calexico'}
->>> [form.cleaned_data for form in formset.deleted_forms]
-[{'votes': 900, 'DELETE': True, 'ORDER': 2, 'choice': u'Fergie'}]
-
-Should be able to get ordered forms from a valid formset even if a
-deleted form would have been invalid.
-
->>> class Person(Form):
-... name = CharField()
-
->>> PeopleForm = formset_factory(
-... form=Person,
-... can_delete=True,
-... can_order=True)
-
->>> p = PeopleForm(
-... {'form-0-name': u'', 'form-0-DELETE': u'on', # no name!
-... 'form-TOTAL_FORMS': 1, 'form-INITIAL_FORMS': 1,
-... 'form-MAX_NUM_FORMS': 1})
-
->>> p.is_valid()
-True
->>> p.ordered_forms
-[]
-
-# FormSet clean hook ##########################################################
-
-FormSets have a hook for doing extra validation that shouldn't be tied to any
-particular form. It follows the same pattern as the clean hook on Forms.
-
-Let's define a FormSet that takes a list of favorite drinks, but raises am
-error if there are any duplicates.
-
->>> class FavoriteDrinkForm(Form):
-... name = CharField()
-...
-
->>> class BaseFavoriteDrinksFormSet(BaseFormSet):
-... def clean(self):
-... seen_drinks = []
-... for drink in self.cleaned_data:
-... if drink['name'] in seen_drinks:
-... raise ValidationError('You may only specify a drink once.')
-... seen_drinks.append(drink['name'])
-...
-
->>> FavoriteDrinksFormSet = formset_factory(FavoriteDrinkForm,
-... formset=BaseFavoriteDrinksFormSet, extra=3)
-
-We start out with a some duplicate data.
-
->>> data = {
-... 'drinks-TOTAL_FORMS': '2', # the number of forms rendered
-... 'drinks-INITIAL_FORMS': '0', # the number of forms with initial data
-... 'drinks-MAX_NUM_FORMS': '0', # max number of forms
-... 'drinks-0-name': 'Gin and Tonic',
-... 'drinks-1-name': 'Gin and Tonic',
-... }
-
->>> formset = FavoriteDrinksFormSet(data, prefix='drinks')
->>> formset.is_valid()
-False
-
-Any errors raised by formset.clean() are available via the
-formset.non_form_errors() method.
-
->>> for error in formset.non_form_errors():
-... print error
-You may only specify a drink once.
-
-
-Make sure we didn't break the valid case.
-
->>> data = {
-... 'drinks-TOTAL_FORMS': '2', # the number of forms rendered
-... 'drinks-INITIAL_FORMS': '0', # the number of forms with initial data
-... 'drinks-MAX_NUM_FORMS': '0', # max number of forms
-... 'drinks-0-name': 'Gin and Tonic',
-... 'drinks-1-name': 'Bloody Mary',
-... }
-
->>> formset = FavoriteDrinksFormSet(data, prefix='drinks')
->>> formset.is_valid()
-True
->>> for error in formset.non_form_errors():
-... print error
-
-# Limiting the maximum number of forms ########################################
-
-# Base case for max_num.
-
-# When not passed, max_num will take its default value of None, i.e. unlimited
-# number of forms, only controlled by the value of the extra parameter.
-
->>> LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=3)
->>> formset = LimitedFavoriteDrinkFormSet()
->>> for form in formset.forms:
-... print form
-<tr><th><label for="id_form-0-name">Name:</label></th><td><input type="text" name="form-0-name" id="id_form-0-name" /></td></tr>
-<tr><th><label for="id_form-1-name">Name:</label></th><td><input type="text" name="form-1-name" id="id_form-1-name" /></td></tr>
-<tr><th><label for="id_form-2-name">Name:</label></th><td><input type="text" name="form-2-name" id="id_form-2-name" /></td></tr>
-
-# If max_num is 0 then no form is rendered at all.
-
->>> LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=3, max_num=0)
->>> formset = LimitedFavoriteDrinkFormSet()
->>> for form in formset.forms:
-... print form
-
->>> LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=5, max_num=2)
->>> formset = LimitedFavoriteDrinkFormSet()
->>> for form in formset.forms:
-... print form
-<tr><th><label for="id_form-0-name">Name:</label></th><td><input type="text" name="form-0-name" id="id_form-0-name" /></td></tr>
-<tr><th><label for="id_form-1-name">Name:</label></th><td><input type="text" name="form-1-name" id="id_form-1-name" /></td></tr>
-
-# Ensure that max_num has no effect when extra is less than max_num.
-
->>> LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=1, max_num=2)
->>> formset = LimitedFavoriteDrinkFormSet()
->>> for form in formset.forms:
-... print form
-<tr><th><label for="id_form-0-name">Name:</label></th><td><input type="text" name="form-0-name" id="id_form-0-name" /></td></tr>
-
-# max_num with initial data
-
-# When not passed, max_num will take its default value of None, i.e. unlimited
-# number of forms, only controlled by the values of the initial and extra
-# parameters.
-
->>> initial = [
-... {'name': 'Fernet and Coke'},
-... ]
->>> LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=1)
->>> formset = LimitedFavoriteDrinkFormSet(initial=initial)
->>> for form in formset.forms:
-... print form
-<tr><th><label for="id_form-0-name">Name:</label></th><td><input type="text" name="form-0-name" value="Fernet and Coke" id="id_form-0-name" /></td></tr>
-<tr><th><label for="id_form-1-name">Name:</label></th><td><input type="text" name="form-1-name" id="id_form-1-name" /></td></tr>
-
-# If max_num is 0 then no form is rendered at all, even if extra and initial
-# are specified.
-
->>> initial = [
-... {'name': 'Fernet and Coke'},
-... {'name': 'Bloody Mary'},
-... ]
->>> LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=1, max_num=0)
->>> formset = LimitedFavoriteDrinkFormSet(initial=initial)
->>> for form in formset.forms:
-... print form
-
-# More initial forms than max_num will result in only the first max_num of
-# them to be displayed with no extra forms.
-
->>> initial = [
-... {'name': 'Gin Tonic'},
-... {'name': 'Bloody Mary'},
-... {'name': 'Jack and Coke'},
-... ]
->>> LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=1, max_num=2)
->>> formset = LimitedFavoriteDrinkFormSet(initial=initial)
->>> for form in formset.forms:
-... print form
-<tr><th><label for="id_form-0-name">Name:</label></th><td><input type="text" name="form-0-name" value="Gin Tonic" id="id_form-0-name" /></td></tr>
-<tr><th><label for="id_form-1-name">Name:</label></th><td><input type="text" name="form-1-name" value="Bloody Mary" id="id_form-1-name" /></td></tr>
-
-# One form from initial and extra=3 with max_num=2 should result in the one
-# initial form and one extra.
-
->>> initial = [
-... {'name': 'Gin Tonic'},
-... ]
->>> LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=3, max_num=2)
->>> formset = LimitedFavoriteDrinkFormSet(initial=initial)
->>> for form in formset.forms:
-... print form
-<tr><th><label for="id_form-0-name">Name:</label></th><td><input type="text" name="form-0-name" value="Gin Tonic" id="id_form-0-name" /></td></tr>
-<tr><th><label for="id_form-1-name">Name:</label></th><td><input type="text" name="form-1-name" id="id_form-1-name" /></td></tr>
-
-
-# Regression test for #6926 ##################################################
-
-Make sure the management form has the correct prefix.
-
->>> formset = FavoriteDrinksFormSet()
->>> formset.management_form.prefix
-'form'
-
->>> formset = FavoriteDrinksFormSet(data={})
->>> formset.management_form.prefix
-'form'
-
->>> formset = FavoriteDrinksFormSet(initial={})
->>> formset.management_form.prefix
-'form'
-
-# Regression test for #12878 #################################################
-
->>> data = {
-... 'drinks-TOTAL_FORMS': '2', # the number of forms rendered
-... 'drinks-INITIAL_FORMS': '0', # the number of forms with initial data
-... 'drinks-MAX_NUM_FORMS': '0', # max number of forms
-... 'drinks-0-name': 'Gin and Tonic',
-... 'drinks-1-name': 'Gin and Tonic',
-... }
-
->>> formset = FavoriteDrinksFormSet(data, prefix='drinks')
->>> formset.is_valid()
-False
->>> print formset.non_form_errors()
-<ul class="errorlist"><li>You may only specify a drink once.</li></ul>
-
-"""
-
-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': 'Calexico',
- 'choices-0-votes': '100',
-}
-
-class Choice(Form):
- choice = CharField()
- votes = IntegerField()
-
-ChoiceFormSet = formset_factory(Choice)
-
-class FormsetAsFooTests(TestCase):
- def test_as_table(self):
- formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
- self.assertEqual(formset.as_table(),"""<input type="hidden" name="choices-TOTAL_FORMS" value="1" /><input type="hidden" name="choices-INITIAL_FORMS" value="0" /><input type="hidden" name="choices-MAX_NUM_FORMS" value="0" />
-<tr><th>Choice:</th><td><input type="text" name="choices-0-choice" value="Calexico" /></td></tr>
-<tr><th>Votes:</th><td><input type="text" name="choices-0-votes" value="100" /></td></tr>""")
-
- def test_as_p(self):
- formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
- self.assertEqual(formset.as_p(),"""<input type="hidden" name="choices-TOTAL_FORMS" value="1" /><input type="hidden" name="choices-INITIAL_FORMS" value="0" /><input type="hidden" name="choices-MAX_NUM_FORMS" value="0" />
-<p>Choice: <input type="text" name="choices-0-choice" value="Calexico" /></p>
-<p>Votes: <input type="text" name="choices-0-votes" value="100" /></p>""")
-
- def test_as_ul(self):
- formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
- self.assertEqual(formset.as_ul(),"""<input type="hidden" name="choices-TOTAL_FORMS" value="1" /><input type="hidden" name="choices-INITIAL_FORMS" value="0" /><input type="hidden" name="choices-MAX_NUM_FORMS" value="0" />
-<li>Choice: <input type="text" name="choices-0-choice" value="Calexico" /></li>
-<li>Votes: <input type="text" name="choices-0-votes" value="100" /></li>""")
-