Fixed #32042 -- Improved error messages for the number of submitted forms in formsets.
This commit is contained in:
parent
91669cc566
commit
848770dd2c
1
AUTHORS
1
AUTHORS
|
@ -627,6 +627,7 @@ answer newbie questions, and generally made Django that much better:
|
|||
Maximilian Merz <django@mxmerz.de>
|
||||
Maximillian Dornseif <md@hudora.de>
|
||||
mccutchen@gmail.com
|
||||
Meghana Bhange <meghanabhange13@gmail.com>
|
||||
Meir Kriheli <http://mksoft.co.il/>
|
||||
Michael S. Brown <michael@msbrown.net>
|
||||
Michael Hall <mhall1@ualberta.ca>
|
||||
|
|
|
@ -342,15 +342,15 @@ class BaseFormSet:
|
|||
self.total_form_count() - len(self.deleted_forms) > self.max_num) or \
|
||||
self.management_form.cleaned_data[TOTAL_FORM_COUNT] > self.absolute_max:
|
||||
raise ValidationError(ngettext(
|
||||
"Please submit %d or fewer forms.",
|
||||
"Please submit %d or fewer forms.", self.max_num) % self.max_num,
|
||||
"Please submit at most %d form.",
|
||||
"Please submit at most %d forms.", self.max_num) % self.max_num,
|
||||
code='too_many_forms',
|
||||
)
|
||||
if (self.validate_min and
|
||||
self.total_form_count() - len(self.deleted_forms) - empty_forms_count < self.min_num):
|
||||
raise ValidationError(ngettext(
|
||||
"Please submit %d or more forms.",
|
||||
"Please submit %d or more forms.", self.min_num) % self.min_num,
|
||||
"Please submit at least %d form.",
|
||||
"Please submit at least %d forms.", self.min_num) % self.min_num,
|
||||
code='too_few_forms')
|
||||
# Give self.clean() a chance to do cross-form validation.
|
||||
self.clean()
|
||||
|
|
|
@ -151,7 +151,7 @@ protects against memory exhaustion attacks using forged ``POST`` requests::
|
|||
>>> formset.is_valid()
|
||||
False
|
||||
>>> formset.non_form_errors()
|
||||
['Please submit 1000 or fewer forms.']
|
||||
['Please submit at most 1000 forms.']
|
||||
|
||||
When ``absolute_max`` is None, it defaults to ``max_num + 1000``. (If
|
||||
``max_num`` is ``None``, it defaults to ``2000``).
|
||||
|
@ -371,7 +371,7 @@ deletion, is less than or equal to ``max_num``.
|
|||
>>> formset.errors
|
||||
[{}, {}]
|
||||
>>> formset.non_form_errors()
|
||||
['Please submit 1 or fewer forms.']
|
||||
['Please submit at most 1 form.']
|
||||
|
||||
``validate_max=True`` validates against ``max_num`` strictly even if
|
||||
``max_num`` was exceeded because the amount of initial data supplied was
|
||||
|
@ -413,7 +413,7 @@ deletion, is greater than or equal to ``min_num``.
|
|||
>>> formset.errors
|
||||
[{}, {}]
|
||||
>>> formset.non_form_errors()
|
||||
['Please submit 3 or more forms.']
|
||||
['Please submit at least 3 forms.']
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
|
@ -336,7 +336,7 @@ class FormsFormsetTestCase(SimpleTestCase):
|
|||
ChoiceFormSet = formset_factory(Choice, extra=1, max_num=1, validate_max=True)
|
||||
formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
|
||||
self.assertFalse(formset.is_valid())
|
||||
self.assertEqual(formset.non_form_errors(), ['Please submit 1 or fewer forms.'])
|
||||
self.assertEqual(formset.non_form_errors(), ['Please submit at most 1 form.'])
|
||||
|
||||
def test_formset_validate_min_flag(self):
|
||||
"""
|
||||
|
@ -358,7 +358,7 @@ class FormsFormsetTestCase(SimpleTestCase):
|
|||
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.'])
|
||||
self.assertEqual(formset.non_form_errors(), ['Please submit at least 3 forms.'])
|
||||
|
||||
def test_formset_validate_min_unchanged_forms(self):
|
||||
"""
|
||||
|
@ -394,7 +394,7 @@ class FormsFormsetTestCase(SimpleTestCase):
|
|||
formset = ChoiceFormSet(data, prefix='choices')
|
||||
self.assertFalse(formset.has_changed())
|
||||
self.assertFalse(formset.is_valid())
|
||||
self.assertEqual(formset.non_form_errors(), ['Please submit 1 or more forms.'])
|
||||
self.assertEqual(formset.non_form_errors(), ['Please submit at least 1 form.'])
|
||||
|
||||
def test_second_form_partially_filled_2(self):
|
||||
"""A partially completed form is invalid."""
|
||||
|
@ -888,7 +888,7 @@ class FormsFormsetTestCase(SimpleTestCase):
|
|||
self.assertIs(formset.is_valid(), False)
|
||||
self.assertEqual(
|
||||
formset.non_form_errors(),
|
||||
['Please submit 1000 or fewer forms.'],
|
||||
['Please submit at most 1000 forms.'],
|
||||
)
|
||||
self.assertEqual(formset.absolute_max, 2000)
|
||||
|
||||
|
@ -912,7 +912,7 @@ class FormsFormsetTestCase(SimpleTestCase):
|
|||
self.assertEqual(len(formset.forms), 3000)
|
||||
self.assertEqual(
|
||||
formset.non_form_errors(),
|
||||
['Please submit 1000 or fewer forms.'],
|
||||
['Please submit at most 1000 forms.'],
|
||||
)
|
||||
|
||||
def test_absolute_max_with_max_num(self):
|
||||
|
@ -931,7 +931,7 @@ class FormsFormsetTestCase(SimpleTestCase):
|
|||
self.assertEqual(len(formset.forms), 1000)
|
||||
self.assertEqual(
|
||||
formset.non_form_errors(),
|
||||
['Please submit 30 or fewer forms.'],
|
||||
['Please submit at most 30 forms.'],
|
||||
)
|
||||
|
||||
def test_absolute_max_invalid(self):
|
||||
|
|
|
@ -250,7 +250,7 @@ id="id_generic_relations-taggeditem-content_type-object_id-1-id"></p>""" % tagge
|
|||
self.assertEqual(len(formset.forms), 1500)
|
||||
self.assertEqual(
|
||||
formset.non_form_errors(),
|
||||
['Please submit 1000 or fewer forms.'],
|
||||
['Please submit at most 1000 forms.'],
|
||||
)
|
||||
|
||||
def test_absolute_max_with_max_num(self):
|
||||
|
@ -269,7 +269,7 @@ id="id_generic_relations-taggeditem-content_type-object_id-1-id"></p>""" % tagge
|
|||
self.assertEqual(len(formset.forms), 100)
|
||||
self.assertEqual(
|
||||
formset.non_form_errors(),
|
||||
['Please submit 20 or fewer forms.'],
|
||||
['Please submit at most 20 forms.'],
|
||||
)
|
||||
|
||||
def test_can_delete_extra(self):
|
||||
|
|
|
@ -1267,7 +1267,7 @@ class ModelFormsetTest(TestCase):
|
|||
FormSet = modelformset_factory(Price, fields="__all__", extra=1, max_num=1, validate_max=True)
|
||||
formset = FormSet(data)
|
||||
self.assertFalse(formset.is_valid())
|
||||
self.assertEqual(formset.non_form_errors(), ['Please submit 1 or fewer forms.'])
|
||||
self.assertEqual(formset.non_form_errors(), ['Please submit at most 1 form.'])
|
||||
|
||||
# Now test the same thing without the validate_max flag to ensure
|
||||
# default behavior is unchanged
|
||||
|
@ -1275,6 +1275,48 @@ class ModelFormsetTest(TestCase):
|
|||
formset = FormSet(data)
|
||||
self.assertTrue(formset.is_valid())
|
||||
|
||||
def test_modelformset_min_num_equals_max_num_less_than(self):
|
||||
data = {
|
||||
'form-TOTAL_FORMS': '3',
|
||||
'form-INITIAL_FORMS': '0',
|
||||
'form-MAX_NUM_FORMS': '2',
|
||||
'form-0-slug': 'car-red',
|
||||
'form-1-slug': 'car-blue',
|
||||
'form-2-slug': 'car-black',
|
||||
}
|
||||
FormSet = modelformset_factory(
|
||||
Product,
|
||||
fields='__all__',
|
||||
extra=1,
|
||||
max_num=2,
|
||||
validate_max=True,
|
||||
min_num=2,
|
||||
validate_min=True,
|
||||
)
|
||||
formset = FormSet(data)
|
||||
self.assertFalse(formset.is_valid())
|
||||
self.assertEqual(formset.non_form_errors(), ['Please submit at most 2 forms.'])
|
||||
|
||||
def test_modelformset_min_num_equals_max_num_more_than(self):
|
||||
data = {
|
||||
'form-TOTAL_FORMS': '1',
|
||||
'form-INITIAL_FORMS': '0',
|
||||
'form-MAX_NUM_FORMS': '2',
|
||||
'form-0-slug': 'car-red',
|
||||
}
|
||||
FormSet = modelformset_factory(
|
||||
Product,
|
||||
fields='__all__',
|
||||
extra=1,
|
||||
max_num=2,
|
||||
validate_max=True,
|
||||
min_num=2,
|
||||
validate_min=True,
|
||||
)
|
||||
formset = FormSet(data)
|
||||
self.assertFalse(formset.is_valid())
|
||||
self.assertEqual(formset.non_form_errors(), ['Please submit at least 2 forms.'])
|
||||
|
||||
def test_unique_together_validation(self):
|
||||
FormSet = modelformset_factory(Price, fields="__all__", extra=1)
|
||||
data = {
|
||||
|
@ -1851,7 +1893,7 @@ class TestModelFormsetOverridesTroughFormMeta(TestCase):
|
|||
self.assertEqual(len(formset.forms), 1500)
|
||||
self.assertEqual(
|
||||
formset.non_form_errors(),
|
||||
['Please submit 1000 or fewer forms.'],
|
||||
['Please submit at most 1000 forms.'],
|
||||
)
|
||||
|
||||
def test_modelformset_factory_absolute_max_with_max_num(self):
|
||||
|
@ -1871,7 +1913,7 @@ class TestModelFormsetOverridesTroughFormMeta(TestCase):
|
|||
self.assertEqual(len(formset.forms), 100)
|
||||
self.assertEqual(
|
||||
formset.non_form_errors(),
|
||||
['Please submit 20 or fewer forms.'],
|
||||
['Please submit at most 20 forms.'],
|
||||
)
|
||||
|
||||
def test_inlineformset_factory_absolute_max(self):
|
||||
|
@ -1892,7 +1934,7 @@ class TestModelFormsetOverridesTroughFormMeta(TestCase):
|
|||
self.assertEqual(len(formset.forms), 1500)
|
||||
self.assertEqual(
|
||||
formset.non_form_errors(),
|
||||
['Please submit 1000 or fewer forms.'],
|
||||
['Please submit at most 1000 forms.'],
|
||||
)
|
||||
|
||||
def test_inlineformset_factory_absolute_max_with_max_num(self):
|
||||
|
@ -1914,7 +1956,7 @@ class TestModelFormsetOverridesTroughFormMeta(TestCase):
|
|||
self.assertEqual(len(formset.forms), 100)
|
||||
self.assertEqual(
|
||||
formset.non_form_errors(),
|
||||
['Please submit 20 or fewer forms.'],
|
||||
['Please submit at most 20 forms.'],
|
||||
)
|
||||
|
||||
def test_modelformset_factory_can_delete_extra(self):
|
||||
|
|
Loading…
Reference in New Issue