Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
D
django
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
django
Commits
df27803a
Kaydet (Commit)
df27803a
authored
May 24, 2013
tarafından
yokomizor
Kaydeden (comit)
Tim Graham
Eyl 19, 2013
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Fixed #9532 -- Added min_num and validate_min on formsets.
Thanks gsf for the suggestion.
üst
59a34c43
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
163 additions
and
22 deletions
+163
-22
formsets.py
django/forms/formsets.py
+22
-5
formsets.txt
docs/ref/forms/formsets.txt
+6
-2
1.7.txt
docs/releases/1.7.txt
+4
-0
formsets.txt
docs/topics/forms/formsets.txt
+44
-3
tests.py
tests/admin_views/tests.py
+5
-5
test_formsets.py
tests/forms_tests/tests/test_formsets.py
+82
-7
No files found.
django/forms/formsets.py
Dosyayı görüntüle @
df27803a
...
...
@@ -18,10 +18,14 @@ __all__ = ('BaseFormSet', 'all_valid')
# special field names
TOTAL_FORM_COUNT
=
'TOTAL_FORMS'
INITIAL_FORM_COUNT
=
'INITIAL_FORMS'
MIN_NUM_FORM_COUNT
=
'MIN_NUM_FORMS'
MAX_NUM_FORM_COUNT
=
'MAX_NUM_FORMS'
ORDERING_FIELD_NAME
=
'ORDER'
DELETION_FIELD_NAME
=
'DELETE'
# default minimum number of forms in a formset
DEFAULT_MIN_NUM
=
0
# default maximum number of forms in a formset, to prevent memory exhaustion
DEFAULT_MAX_NUM
=
1000
...
...
@@ -34,9 +38,10 @@ class ManagementForm(Form):
def
__init__
(
self
,
*
args
,
**
kwargs
):
self
.
base_fields
[
TOTAL_FORM_COUNT
]
=
IntegerField
(
widget
=
HiddenInput
)
self
.
base_fields
[
INITIAL_FORM_COUNT
]
=
IntegerField
(
widget
=
HiddenInput
)
# MAX_NUM_FORM_COUNT is output with the rest of the management form,
# but only for the convenience of client-side code. The POST
# value of MAX_NUM_FORM_COUNT returned from the client is not checked.
# MIN_NUM_FORM_COUNT and MAX_NUM_FORM_COUNT are output with the rest of
# the management form, but only for the convenience of client-side
# code. The POST value of them returned from the client is not checked.
self
.
base_fields
[
MIN_NUM_FORM_COUNT
]
=
IntegerField
(
required
=
False
,
widget
=
HiddenInput
)
self
.
base_fields
[
MAX_NUM_FORM_COUNT
]
=
IntegerField
(
required
=
False
,
widget
=
HiddenInput
)
super
(
ManagementForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
...
...
@@ -92,6 +97,7 @@ class BaseFormSet(object):
form
=
ManagementForm
(
auto_id
=
self
.
auto_id
,
prefix
=
self
.
prefix
,
initial
=
{
TOTAL_FORM_COUNT
:
self
.
total_form_count
(),
INITIAL_FORM_COUNT
:
self
.
initial_form_count
(),
MIN_NUM_FORM_COUNT
:
self
.
min_num
,
MAX_NUM_FORM_COUNT
:
self
.
max_num
})
return
form
...
...
@@ -323,6 +329,12 @@ class BaseFormSet(object):
"Please submit
%
d or fewer forms."
,
self
.
max_num
)
%
self
.
max_num
,
code
=
'too_many_forms'
,
)
if
(
self
.
validate_min
and
self
.
total_form_count
()
-
len
(
self
.
deleted_forms
)
<
self
.
min_num
):
raise
ValidationError
(
ungettext
(
"Please submit
%
d or more forms."
,
"Please submit
%
d or more forms."
,
self
.
min_num
)
%
self
.
min_num
,
code
=
'too_few_forms'
)
# Give self.clean() a chance to do cross-form validation.
self
.
clean
()
except
ValidationError
as
e
:
...
...
@@ -395,17 +407,22 @@ class BaseFormSet(object):
return
mark_safe
(
'
\n
'
.
join
([
six
.
text_type
(
self
.
management_form
),
forms
]))
def
formset_factory
(
form
,
formset
=
BaseFormSet
,
extra
=
1
,
can_order
=
False
,
can_delete
=
False
,
max_num
=
None
,
validate_max
=
False
):
can_delete
=
False
,
max_num
=
None
,
validate_max
=
False
,
min_num
=
None
,
validate_min
=
False
):
"""Return a FormSet for the given form class."""
if
min_num
is
None
:
min_num
=
DEFAULT_MIN_NUM
if
max_num
is
None
:
max_num
=
DEFAULT_MAX_NUM
# hard limit on forms instantiated, to prevent memory-exhaustion attacks
# limit is simply max_num + DEFAULT_MAX_NUM (which is 2*DEFAULT_MAX_NUM
# if max_num is None in the first place)
absolute_max
=
max_num
+
DEFAULT_MAX_NUM
extra
+=
min_num
attrs
=
{
'form'
:
form
,
'extra'
:
extra
,
'can_order'
:
can_order
,
'can_delete'
:
can_delete
,
'max_num'
:
max_num
,
'absolute_max'
:
absolute_max
,
'min_num'
:
min_num
,
'max_num'
:
max_num
,
'absolute_max'
:
absolute_max
,
'validate_min'
:
validate_min
,
'validate_max'
:
validate_max
}
return
type
(
form
.
__name__
+
str
(
'FormSet'
),
(
formset
,),
attrs
)
...
...
docs/ref/forms/formsets.txt
Dosyayı görüntüle @
df27803a
...
...
@@ -5,12 +5,16 @@ Formset Functions
.. module:: django.forms.formsets
:synopsis: Django's functions for building formsets.
.. function:: formset_factory(form, formset=BaseFormSet, extra=1, can_order=False, can_delete=False, max_num=None, validate_max=False)
.. function:: formset_factory(form, formset=BaseFormSet, extra=1, can_order=False, can_delete=False, max_num=None, validate_max=False
, min_num=None, validate_min=False
)
Returns a ``FormSet`` class for the given ``form`` class.
See :ref:`formsets` for example usage.
.. versionchanged:: 1.6
The ``validate_max`` parameter was added.
.. versionchanged:: 1.7
The ``min_num`` and ``validate_min`` parameters were added.
docs/releases/1.7.txt
Dosyayı görüntüle @
df27803a
...
...
@@ -234,6 +234,10 @@ Forms
<django.forms.extras.widgets.SelectDateWidget.months>` can be used to
customize the wording of the months displayed in the select widget.
* The ``min_num`` and ``validate_min`` parameters were added to
:func:`~django.forms.formsets.formset_factory` to allow validating
a minimum number of submitted forms.
Management Commands
^^^^^^^^^^^^^^^^^^^
...
...
docs/topics/forms/formsets.txt
Dosyayı görüntüle @
df27803a
...
...
@@ -298,6 +298,13 @@ method on the formset.
Validating the number of forms in a formset
-------------------------------------------
Django provides a couple ways to validate the minimum or maximum number of
submitted forms. Applications which need more customizable validation of the
number of forms should use custom formset validation.
``validate_max``
~~~~~~~~~~~~~~~~
If ``validate_max=True`` is passed to
:func:`~django.forms.formsets.formset_factory`, validation will also check
that the number of forms in the data set, minus those marked for
...
...
@@ -309,6 +316,7 @@ deletion, is less than or equal to ``max_num``.
>>> data = {
... 'form-TOTAL_FORMS': u'2',
... 'form-INITIAL_FORMS': u'0',
... 'form-MIN_NUM_FORMS': u'',
... 'form-MAX_NUM_FORMS': u'',
... 'form-0-title': u'Test',
... 'form-0-pub_date': u'1904-06-16',
...
...
@@ -327,9 +335,6 @@ deletion, is less than or equal to ``max_num``.
``max_num`` was exceeded because the amount of initial data supplied was
excessive.
Applications which need more customizable validation of the number of forms
should use custom formset validation.
.. note::
Regardless of ``validate_max``, if the number of forms in a data set
...
...
@@ -344,6 +349,42 @@ should use custom formset validation.
The ``validate_max`` parameter was added to
:func:`~django.forms.formsets.formset_factory`.
``validate_min``
~~~~~~~~~~~~~~~~
.. versionadded:: 1.7
If ``validate_min=True`` is passed to
:func:`~django.forms.formsets.formset_factory`, validation will also check
that the number of forms in the data set, minus those marked for
deletion, is greater than or equal to ``min_num``.
>>> from django.forms.formsets import formset_factory
>>> from myapp.forms import ArticleForm
>>> ArticleFormSet = formset_factory(ArticleForm, min_num=3, validate_min=True)
>>> data = {
... 'form-TOTAL_FORMS': u'2',
... 'form-INITIAL_FORMS': u'0',
... 'form-MIN_NUM_FORMS': u'',
... 'form-MAX_NUM_FORMS': u'',
... 'form-0-title': u'Test',
... 'form-0-pub_date': u'1904-06-16',
... 'form-1-title': u'Test 2',
... 'form-1-pub_date': u'1912-06-23',
... }
>>> formset = ArticleFormSet(data)
>>> formset.is_valid()
False
>>> formset.errors
[{}, {}]
>>> formset.non_form_errors()
[u'Please submit 3 or more forms.']
.. versionchanged:: 1.7
The ``min_num`` and ``validate_min`` parameters were added to
:func:`~django.forms.formsets.formset_factory`.
Dealing with ordering and deletion of forms
-------------------------------------------
...
...
tests/admin_views/tests.py
Dosyayı görüntüle @
df27803a
...
...
@@ -1874,14 +1874,14 @@ class AdminViewListEditable(TestCase):
def
test_changelist_input_html
(
self
):
response
=
self
.
client
.
get
(
'/test_admin/admin/admin_views/person/'
)
# 2 inputs per object(the field and the hidden id field) = 6
#
3 management hidden fields = 3
#
4 management hidden fields = 4
# 4 action inputs (3 regular checkboxes, 1 checkbox to select all)
# main form submit button = 1
# search field and search submit button = 2
# CSRF field = 1
# field to track 'select all' across paginated views = 1
# 6 +
3 + 4 + 1 + 2 + 1 + 1 = 18
inputs
self
.
assertContains
(
response
,
"<input"
,
count
=
1
8
)
# 6 +
4 + 4 + 1 + 2 + 1 + 1 = 19
inputs
self
.
assertContains
(
response
,
"<input"
,
count
=
1
9
)
# 1 select per object = 3 selects
self
.
assertContains
(
response
,
"<select"
,
count
=
4
)
...
...
@@ -3629,9 +3629,9 @@ class ReadonlyTest(TestCase):
response
=
self
.
client
.
get
(
'/test_admin/admin/admin_views/post/add/'
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertNotContains
(
response
,
'name="posted"'
)
# 3 fields + 2 submit buttons +
4
inline management form fields, + 2
# 3 fields + 2 submit buttons +
5
inline management form fields, + 2
# hidden fields for inlines + 1 field for the inline + 2 empty form
self
.
assertContains
(
response
,
"<input"
,
count
=
1
4
)
self
.
assertContains
(
response
,
"<input"
,
count
=
1
5
)
self
.
assertContains
(
response
,
formats
.
localize
(
datetime
.
date
.
today
()))
self
.
assertContains
(
response
,
"<label>Awesomeness level:</label>"
)
...
...
tests/forms_tests/tests/test_formsets.py
Dosyayı görüntüle @
df27803a
...
...
@@ -57,7 +57,7 @@ SplitDateTimeFormSet = formset_factory(SplitDateTimeForm)
class
FormsFormsetTestCase
(
TestCase
):
def
make_choiceformset
(
self
,
formset_data
=
None
,
formset_class
=
ChoiceFormSet
,
total_forms
=
None
,
initial_forms
=
0
,
max_num_forms
=
0
,
**
kwargs
):
total_forms
=
None
,
initial_forms
=
0
,
max_num_forms
=
0
,
min_num_forms
=
0
,
**
kwargs
):
"""
Make a ChoiceFormset from the given formset_data.
The data should be given as a list of (choice, votes) tuples.
...
...
@@ -79,6 +79,7 @@ class FormsFormsetTestCase(TestCase):
prefixed
(
'TOTAL_FORMS'
):
str
(
total_forms
),
prefixed
(
'INITIAL_FORMS'
):
str
(
initial_forms
),
prefixed
(
'MAX_NUM_FORMS'
):
str
(
max_num_forms
),
prefixed
(
'MIN_NUM_FORMS'
):
str
(
min_num_forms
),
}
for
i
,
(
choice
,
votes
)
in
enumerate
(
formset_data
):
data
[
prefixed
(
str
(
i
),
'choice'
)]
=
choice
...
...
@@ -91,8 +92,7 @@ class FormsFormsetTestCase(TestCase):
# 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
=
self
.
make_choiceformset
()
self
.
assertHTMLEqual
(
str
(
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" value="1000" />
self
.
assertHTMLEqual
(
str
(
formset
),
"""<input type="hidden" name="choices-TOTAL_FORMS" value="1" /><input type="hidden" name="choices-INITIAL_FORMS" value="0" /><input type="hidden" name="choices-MIN_NUM_FORMS" value="0" /><input type="hidden" name="choices-MAX_NUM_FORMS" value="1000" />
<tr><th>Choice:</th><td><input type="text" name="choices-0-choice" /></td></tr>
<tr><th>Votes:</th><td><input type="number" name="choices-0-votes" /></td></tr>"""
)
...
...
@@ -200,6 +200,7 @@ class FormsFormsetTestCase(TestCase):
data
=
{
'choices-TOTAL_FORMS'
:
'3'
,
# the number of forms rendered
'choices-INITIAL_FORMS'
:
'0'
,
# the number of forms with initial data
'choices-MIN_NUM_FORMS'
:
'0'
,
# min number of forms
'choices-MAX_NUM_FORMS'
:
'0'
,
# max number of forms
'choices-0-choice'
:
''
,
'choices-0-votes'
:
''
,
...
...
@@ -213,12 +214,46 @@ class FormsFormsetTestCase(TestCase):
self
.
assertTrue
(
formset
.
is_valid
())
self
.
assertEqual
([
form
.
cleaned_data
for
form
in
formset
.
forms
],
[{},
{},
{}])
def
test_min_num_displaying_more_than_one_blank_form
(
self
):
# We can also display more than 1 empty form passing min_num argument
# to formset_factory. It will increment the extra argument
ChoiceFormSet
=
formset_factory
(
Choice
,
extra
=
1
,
min_num
=
1
)
formset
=
ChoiceFormSet
(
auto_id
=
False
,
prefix
=
'choices'
)
form_output
=
[]
for
form
in
formset
.
forms
:
form_output
.
append
(
form
.
as_ul
())
self
.
assertHTMLEqual
(
'
\n
'
.
join
(
form_output
),
"""<li>Choice: <input type="text" name="choices-0-choice" /></li>
<li>Votes: <input type="number" name="choices-0-votes" /></li>
<li>Choice: <input type="text" name="choices-1-choice" /></li>
<li>Votes: <input type="number" name="choices-1-votes" /></li>"""
)
def
test_min_num_displaying_more_than_one_blank_form_with_zero_extra
(
self
):
# We can also display more than 1 empty form passing min_num argument
ChoiceFormSet
=
formset_factory
(
Choice
,
extra
=
0
,
min_num
=
3
)
formset
=
ChoiceFormSet
(
auto_id
=
False
,
prefix
=
'choices'
)
form_output
=
[]
for
form
in
formset
.
forms
:
form_output
.
append
(
form
.
as_ul
())
self
.
assertHTMLEqual
(
'
\n
'
.
join
(
form_output
),
"""<li>Choice: <input type="text" name="choices-0-choice" /></li>
<li>Votes: <input type="number" name="choices-0-votes" /></li>
<li>Choice: <input type="text" name="choices-1-choice" /></li>
<li>Votes: <input type="number" name="choices-1-votes" /></li>
<li>Choice: <input type="text" name="choices-2-choice" /></li>
<li>Votes: <input type="number" name="choices-2-votes" /></li>"""
)
def
test_single_form_completed
(
self
):
# 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-MIN_NUM_FORMS'
:
'0'
,
# min number of forms
'choices-MAX_NUM_FORMS'
:
'0'
,
# max number of forms
'choices-0-choice'
:
'Calexico'
,
'choices-0-votes'
:
'100'
,
...
...
@@ -242,6 +277,7 @@ class FormsFormsetTestCase(TestCase):
data
=
{
'choices-TOTAL_FORMS'
:
'2'
,
# the number of forms rendered
'choices-INITIAL_FORMS'
:
'0'
,
# the number of forms with initial data
'choices-MIN_NUM_FORMS'
:
'0'
,
# min number of forms
'choices-MAX_NUM_FORMS'
:
'2'
,
# max number of forms - should be ignored
'choices-0-choice'
:
'Zero'
,
'choices-0-votes'
:
'0'
,
...
...
@@ -254,12 +290,35 @@ class FormsFormsetTestCase(TestCase):
self
.
assertFalse
(
formset
.
is_valid
())
self
.
assertEqual
(
formset
.
non_form_errors
(),
[
'Please submit 1 or fewer forms.'
])
def
test_formset_validate_min_flag
(
self
):
# If validate_min is set and min_num is more than TOTAL_FORMS in the
# data, then throw an exception. MIN_NUM_FORMS in the data is
# irrelevant here (it's output as a hint for the client but its
# value in the returned data is not checked)
data
=
{
'choices-TOTAL_FORMS'
:
'2'
,
# the number of forms rendered
'choices-INITIAL_FORMS'
:
'0'
,
# the number of forms with initial data
'choices-MIN_NUM_FORMS'
:
'0'
,
# min number of forms
'choices-MAX_NUM_FORMS'
:
'0'
,
# max number of forms - should be ignored
'choices-0-choice'
:
'Zero'
,
'choices-0-votes'
:
'0'
,
'choices-1-choice'
:
'One'
,
'choices-1-votes'
:
'1'
,
}
ChoiceFormSet
=
formset_factory
(
Choice
,
extra
=
1
,
min_num
=
3
,
validate_min
=
True
)
formset
=
ChoiceFormSet
(
data
,
auto_id
=
False
,
prefix
=
'choices'
)
self
.
assertFalse
(
formset
.
is_valid
())
self
.
assertEqual
(
formset
.
non_form_errors
(),
[
'Please submit 3 or more forms.'
])
def
test_second_form_partially_filled_2
(
self
):
# 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-MIN_NUM_FORMS'
:
'0'
,
# min number of forms
'choices-MAX_NUM_FORMS'
:
'0'
,
# max number of forms
'choices-0-choice'
:
'Calexico'
,
'choices-0-votes'
:
'100'
,
...
...
@@ -281,6 +340,7 @@ class FormsFormsetTestCase(TestCase):
data
=
{
'choices-TOTAL_FORMS'
:
'3'
,
# the number of forms rendered
'choices-INITIAL_FORMS'
:
'0'
,
# the number of forms with initial data
'choices-MIN_NUM_FORMS'
:
'0'
,
# min number of forms
'choices-MAX_NUM_FORMS'
:
'0'
,
# max number of forms
'choices-0-choice'
:
'Calexico'
,
'choices-0-votes'
:
'100'
,
...
...
@@ -344,6 +404,7 @@ class FormsFormsetTestCase(TestCase):
data
=
{
'choices-TOTAL_FORMS'
:
'3'
,
# the number of forms rendered
'choices-INITIAL_FORMS'
:
'2'
,
# the number of forms with initial data
'choices-MIN_NUM_FORMS'
:
'0'
,
# min number of forms
'choices-MAX_NUM_FORMS'
:
'0'
,
# max number of forms
'choices-0-choice'
:
'Calexico'
,
'choices-0-votes'
:
'100'
,
...
...
@@ -371,6 +432,7 @@ class FormsFormsetTestCase(TestCase):
data
=
{
'check-TOTAL_FORMS'
:
'3'
,
# the number of forms rendered
'check-INITIAL_FORMS'
:
'2'
,
# the number of forms with initial data
'choices-MIN_NUM_FORMS'
:
'0'
,
# min number of forms
'check-MAX_NUM_FORMS'
:
'0'
,
# max number of forms
'check-0-field'
:
'200'
,
'check-0-DELETE'
:
''
,
...
...
@@ -401,7 +463,7 @@ class FormsFormsetTestCase(TestCase):
p
=
PeopleForm
(
{
'form-0-name'
:
''
,
'form-0-DELETE'
:
'on'
,
# no name!
'form-TOTAL_FORMS'
:
1
,
'form-INITIAL_FORMS'
:
1
,
'form-MAX_NUM_FORMS'
:
1
})
'form-M
IN_NUM_FORMS'
:
0
,
'form-M
AX_NUM_FORMS'
:
1
})
self
.
assertTrue
(
p
.
is_valid
())
self
.
assertEqual
(
len
(
p
.
deleted_forms
),
1
)
...
...
@@ -438,6 +500,7 @@ class FormsFormsetTestCase(TestCase):
data
=
{
'choices-TOTAL_FORMS'
:
'3'
,
# the number of forms rendered
'choices-INITIAL_FORMS'
:
'2'
,
# the number of forms with initial data
'choices-MIN_NUM_FORMS'
:
'0'
,
# min number of forms
'choices-MAX_NUM_FORMS'
:
'0'
,
# max number of forms
'choices-0-choice'
:
'Calexico'
,
'choices-0-votes'
:
'100'
,
...
...
@@ -470,6 +533,7 @@ class FormsFormsetTestCase(TestCase):
data
=
{
'choices-TOTAL_FORMS'
:
'4'
,
# the number of forms rendered
'choices-INITIAL_FORMS'
:
'3'
,
# the number of forms with initial data
'choices-MIN_NUM_FORMS'
:
'0'
,
# min number of forms
'choices-MAX_NUM_FORMS'
:
'0'
,
# max number of forms
'choices-0-choice'
:
'Calexico'
,
'choices-0-votes'
:
'100'
,
...
...
@@ -506,6 +570,7 @@ class FormsFormsetTestCase(TestCase):
data
=
{
'choices-TOTAL_FORMS'
:
'3'
,
# the number of forms rendered
'choices-INITIAL_FORMS'
:
'0'
,
# the number of forms with initial data
'choices-MIN_NUM_FORMS'
:
'0'
,
# min number of forms
'choices-MAX_NUM_FORMS'
:
'0'
,
# max number of forms
}
...
...
@@ -558,6 +623,7 @@ class FormsFormsetTestCase(TestCase):
data
=
{
'choices-TOTAL_FORMS'
:
'4'
,
# the number of forms rendered
'choices-INITIAL_FORMS'
:
'3'
,
# the number of forms with initial data
'choices-MIN_NUM_FORMS'
:
'0'
,
# min number of forms
'choices-MAX_NUM_FORMS'
:
'0'
,
# max number of forms
'choices-0-choice'
:
'Calexico'
,
'choices-0-votes'
:
'100'
,
...
...
@@ -604,6 +670,7 @@ class FormsFormsetTestCase(TestCase):
'form-0-DELETE'
:
'on'
,
# no name!
'form-TOTAL_FORMS'
:
1
,
'form-INITIAL_FORMS'
:
1
,
'form-MIN_NUM_FORMS'
:
0
,
'form-MAX_NUM_FORMS'
:
1
})
...
...
@@ -620,6 +687,7 @@ class FormsFormsetTestCase(TestCase):
data
=
{
'drinks-TOTAL_FORMS'
:
'2'
,
# the number of forms rendered
'drinks-INITIAL_FORMS'
:
'0'
,
# the number of forms with initial data
'drinks-MIN_NUM_FORMS'
:
'0'
,
# min number of forms
'drinks-MAX_NUM_FORMS'
:
'0'
,
# max number of forms
'drinks-0-name'
:
'Gin and Tonic'
,
'drinks-1-name'
:
'Gin and Tonic'
,
...
...
@@ -639,6 +707,7 @@ class FormsFormsetTestCase(TestCase):
data
=
{
'drinks-TOTAL_FORMS'
:
'2'
,
# the number of forms rendered
'drinks-INITIAL_FORMS'
:
'0'
,
# the number of forms with initial data
'drinks-MIN_NUM_FORMS'
:
'0'
,
# min number of forms
'drinks-MAX_NUM_FORMS'
:
'0'
,
# max number of forms
'drinks-0-name'
:
'Gin and Tonic'
,
'drinks-1-name'
:
'Bloody Mary'
,
...
...
@@ -791,6 +860,7 @@ class FormsFormsetTestCase(TestCase):
data
=
{
'form-TOTAL_FORMS'
:
'2'
,
'form-INITIAL_FORMS'
:
'0'
,
'form-MIN_NUM_FORMS'
:
'0'
,
'form-MAX_NUM_FORMS'
:
'0'
,
}
formset
=
FavoriteDrinksFormSet
(
data
=
data
)
...
...
@@ -805,6 +875,7 @@ class FormsFormsetTestCase(TestCase):
data
=
{
'drinks-TOTAL_FORMS'
:
'2'
,
# the number of forms rendered
'drinks-INITIAL_FORMS'
:
'0'
,
# the number of forms with initial data
'drinks-MIN_NUM_FORMS'
:
'0'
,
# min number of forms
'drinks-MAX_NUM_FORMS'
:
'0'
,
# max number of forms
'drinks-0-name'
:
'Gin and Tonic'
,
'drinks-1-name'
:
'Gin and Tonic'
,
...
...
@@ -894,6 +965,7 @@ class FormsFormsetTestCase(TestCase):
data
=
{
'choices-TOTAL_FORMS'
:
'1'
,
# number of forms rendered
'choices-INITIAL_FORMS'
:
'0'
,
# number of forms with initial data
'choices-MIN_NUM_FORMS'
:
'0'
,
# min number of forms
'choices-MAX_NUM_FORMS'
:
'0'
,
# max number of forms
'choices-0-choice'
:
'Calexico'
,
'choices-0-votes'
:
'100'
,
...
...
@@ -914,6 +986,7 @@ class FormsFormsetTestCase(TestCase):
{
'choices-TOTAL_FORMS'
:
'4'
,
'choices-INITIAL_FORMS'
:
'0'
,
'choices-MIN_NUM_FORMS'
:
'0'
,
# min number of forms
'choices-MAX_NUM_FORMS'
:
'4'
,
'choices-0-choice'
:
'Zero'
,
'choices-0-votes'
:
'0'
,
...
...
@@ -945,6 +1018,7 @@ class FormsFormsetTestCase(TestCase):
{
'choices-TOTAL_FORMS'
:
'4'
,
'choices-INITIAL_FORMS'
:
'0'
,
'choices-MIN_NUM_FORMS'
:
'0'
,
# min number of forms
'choices-MAX_NUM_FORMS'
:
'4'
,
'choices-0-choice'
:
'Zero'
,
'choices-0-votes'
:
'0'
,
...
...
@@ -1032,6 +1106,7 @@ class FormsFormsetTestCase(TestCase):
data
=
{
'choices-TOTAL_FORMS'
:
'1'
,
# the number of forms rendered
'choices-INITIAL_FORMS'
:
'0'
,
# the number of forms with initial data
'choices-MIN_NUM_FORMS'
:
'0'
,
# min number of forms
'choices-MAX_NUM_FORMS'
:
'0'
,
# max number of forms
'choices-0-choice'
:
'Calexico'
,
'choices-0-votes'
:
'100'
,
...
...
@@ -1046,19 +1121,19 @@ ChoiceFormSet = formset_factory(Choice)
class
FormsetAsFooTests
(
TestCase
):
def
test_as_table
(
self
):
formset
=
ChoiceFormSet
(
data
,
auto_id
=
False
,
prefix
=
'choices'
)
self
.
assertHTMLEqual
(
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" />
self
.
assertHTMLEqual
(
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-M
IN_NUM_FORMS" value="0" /><input type="hidden" name="choices-M
AX_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="number" name="choices-0-votes" value="100" /></td></tr>"""
)
def
test_as_p
(
self
):
formset
=
ChoiceFormSet
(
data
,
auto_id
=
False
,
prefix
=
'choices'
)
self
.
assertHTMLEqual
(
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" />
self
.
assertHTMLEqual
(
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-M
IN_NUM_FORMS" value="0" /><input type="hidden" name="choices-M
AX_NUM_FORMS" value="0" />
<p>Choice: <input type="text" name="choices-0-choice" value="Calexico" /></p>
<p>Votes: <input type="number" name="choices-0-votes" value="100" /></p>"""
)
def
test_as_ul
(
self
):
formset
=
ChoiceFormSet
(
data
,
auto_id
=
False
,
prefix
=
'choices'
)
self
.
assertHTMLEqual
(
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" />
self
.
assertHTMLEqual
(
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-M
IN_NUM_FORMS" value="0" /><input type="hidden" name="choices-M
AX_NUM_FORMS" value="0" />
<li>Choice: <input type="text" name="choices-0-choice" value="Calexico" /></li>
<li>Votes: <input type="number" name="choices-0-votes" value="100" /></li>"""
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment