summaryrefslogtreecommitdiff
path: root/tests/forms_tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests/forms_tests')
-rw-r--r--tests/forms_tests/field_tests/__init__.py4
-rw-r--r--tests/forms_tests/field_tests/test_base.py13
-rw-r--r--tests/forms_tests/field_tests/test_booleanfield.py47
-rw-r--r--tests/forms_tests/field_tests/test_charfield.py100
-rw-r--r--tests/forms_tests/field_tests/test_choicefield.py73
-rw-r--r--tests/forms_tests/field_tests/test_combofield.py37
-rw-r--r--tests/forms_tests/field_tests/test_datefield.py183
-rw-r--r--tests/forms_tests/field_tests/test_datetimefield.py125
-rw-r--r--tests/forms_tests/field_tests/test_decimalfield.py193
-rw-r--r--tests/forms_tests/field_tests/test_durationfield.py37
-rw-r--r--tests/forms_tests/field_tests/test_emailfield.py55
-rw-r--r--tests/forms_tests/field_tests/test_filefield.py88
-rw-r--r--tests/forms_tests/field_tests/test_filepathfield.py105
-rw-r--r--tests/forms_tests/field_tests/test_floatfield.py85
-rw-r--r--tests/forms_tests/field_tests/test_genericipaddressfield.py219
-rw-r--r--tests/forms_tests/field_tests/test_imagefield.py74
-rw-r--r--tests/forms_tests/field_tests/test_integerfield.py112
-rw-r--r--tests/forms_tests/field_tests/test_jsonfield.py71
-rw-r--r--tests/forms_tests/field_tests/test_multiplechoicefield.py75
-rw-r--r--tests/forms_tests/field_tests/test_multivaluefield.py115
-rw-r--r--tests/forms_tests/field_tests/test_nullbooleanfield.py52
-rw-r--r--tests/forms_tests/field_tests/test_regexfield.py92
-rw-r--r--tests/forms_tests/field_tests/test_slugfield.py23
-rw-r--r--tests/forms_tests/field_tests/test_splitdatetimefield.py75
-rw-r--r--tests/forms_tests/field_tests/test_timefield.py31
-rw-r--r--tests/forms_tests/field_tests/test_typedchoicefield.py62
-rw-r--r--tests/forms_tests/field_tests/test_typedmultiplechoicefield.py44
-rw-r--r--tests/forms_tests/field_tests/test_urlfield.py116
-rw-r--r--tests/forms_tests/field_tests/test_uuidfield.py19
-rw-r--r--tests/forms_tests/models.py44
-rw-r--r--tests/forms_tests/tests/__init__.py6
-rw-r--r--tests/forms_tests/tests/test_deprecation_forms.py67
-rw-r--r--tests/forms_tests/tests/test_error_messages.py322
-rw-r--r--tests/forms_tests/tests/test_forms.py2564
-rw-r--r--tests/forms_tests/tests/test_formsets.py1183
-rw-r--r--tests/forms_tests/tests/test_i18n.py62
-rw-r--r--tests/forms_tests/tests/test_input_formats.py304
-rw-r--r--tests/forms_tests/tests/test_media.py412
-rw-r--r--tests/forms_tests/tests/test_renderers.py24
-rw-r--r--tests/forms_tests/tests/test_utils.py215
-rw-r--r--tests/forms_tests/tests/test_validators.py122
-rw-r--r--tests/forms_tests/tests/test_widgets.py11
-rw-r--r--tests/forms_tests/tests/tests.py200
-rw-r--r--tests/forms_tests/urls.py4
-rw-r--r--tests/forms_tests/views.py8
-rw-r--r--tests/forms_tests/widget_tests/base.py22
-rw-r--r--tests/forms_tests/widget_tests/test_checkboxinput.py89
-rw-r--r--tests/forms_tests/widget_tests/test_checkboxselectmultiple.py100
-rw-r--r--tests/forms_tests/widget_tests/test_clearablefileinput.py101
-rw-r--r--tests/forms_tests/widget_tests/test_dateinput.py43
-rw-r--r--tests/forms_tests/widget_tests/test_datetimeinput.py74
-rw-r--r--tests/forms_tests/widget_tests/test_fileinput.py23
-rw-r--r--tests/forms_tests/widget_tests/test_hiddeninput.py8
-rw-r--r--tests/forms_tests/widget_tests/test_input.py20
-rw-r--r--tests/forms_tests/widget_tests/test_multiplehiddeninput.py44
-rw-r--r--tests/forms_tests/widget_tests/test_multiwidget.py203
-rw-r--r--tests/forms_tests/widget_tests/test_nullbooleanselect.py112
-rw-r--r--tests/forms_tests/widget_tests/test_numberinput.py9
-rw-r--r--tests/forms_tests/widget_tests/test_passwordinput.py23
-rw-r--r--tests/forms_tests/widget_tests/test_radioselect.py69
-rw-r--r--tests/forms_tests/widget_tests/test_select.py375
-rw-r--r--tests/forms_tests/widget_tests/test_selectdatewidget.py240
-rw-r--r--tests/forms_tests/widget_tests/test_selectmultiple.py134
-rw-r--r--tests/forms_tests/widget_tests/test_splitdatetimewidget.py93
-rw-r--r--tests/forms_tests/widget_tests/test_splithiddendatetimewidget.py81
-rw-r--r--tests/forms_tests/widget_tests/test_textarea.py52
-rw-r--r--tests/forms_tests/widget_tests/test_textinput.py79
-rw-r--r--tests/forms_tests/widget_tests/test_timeinput.py55
-rw-r--r--tests/forms_tests/widget_tests/test_widget.py23
69 files changed, 5883 insertions, 4062 deletions
diff --git a/tests/forms_tests/field_tests/__init__.py b/tests/forms_tests/field_tests/__init__.py
index 4aae30282b..94b2a91242 100644
--- a/tests/forms_tests/field_tests/__init__.py
+++ b/tests/forms_tests/field_tests/__init__.py
@@ -2,8 +2,8 @@ from django import forms
class FormFieldAssertionsMixin:
-
def assertWidgetRendersTo(self, field, to):
class Form(forms.Form):
f = field
- self.assertHTMLEqual(str(Form()['f']), to)
+
+ self.assertHTMLEqual(str(Form()["f"]), to)
diff --git a/tests/forms_tests/field_tests/test_base.py b/tests/forms_tests/field_tests/test_base.py
index 4ddbea3414..201e05e47e 100644
--- a/tests/forms_tests/field_tests/test_base.py
+++ b/tests/forms_tests/field_tests/test_base.py
@@ -3,7 +3,6 @@ from django.test import SimpleTestCase
class BasicFieldsTests(SimpleTestCase):
-
def test_field_sets_widget_is_required(self):
self.assertTrue(Field(required=True).widget.is_required)
self.assertFalse(Field(required=False).widget.is_required)
@@ -23,20 +22,20 @@ class BasicFieldsTests(SimpleTestCase):
def test_field_deepcopies_widget_instance(self):
class CustomChoiceField(ChoiceField):
- widget = Select(attrs={'class': 'my-custom-class'})
+ widget = Select(attrs={"class": "my-custom-class"})
class TestForm(Form):
field1 = CustomChoiceField(choices=[])
field2 = CustomChoiceField(choices=[])
f = TestForm()
- f.fields['field1'].choices = [('1', '1')]
- f.fields['field2'].choices = [('2', '2')]
- self.assertEqual(f.fields['field1'].widget.choices, [('1', '1')])
- self.assertEqual(f.fields['field2'].widget.choices, [('2', '2')])
+ f.fields["field1"].choices = [("1", "1")]
+ f.fields["field2"].choices = [("2", "2")]
+ self.assertEqual(f.fields["field1"].widget.choices, [("1", "1")])
+ self.assertEqual(f.fields["field2"].widget.choices, [("2", "2")])
class DisabledFieldTests(SimpleTestCase):
def test_disabled_field_has_changed_always_false(self):
disabled_field = Field(disabled=True)
- self.assertFalse(disabled_field.has_changed('x', 'y'))
+ self.assertFalse(disabled_field.has_changed("x", "y"))
diff --git a/tests/forms_tests/field_tests/test_booleanfield.py b/tests/forms_tests/field_tests/test_booleanfield.py
index b0153e9e0b..560a0f473b 100644
--- a/tests/forms_tests/field_tests/test_booleanfield.py
+++ b/tests/forms_tests/field_tests/test_booleanfield.py
@@ -6,11 +6,10 @@ from django.test import SimpleTestCase
class BooleanFieldTest(SimpleTestCase):
-
def test_booleanfield_clean_1(self):
f = BooleanField()
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('')
+ f.clean("")
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(None)
self.assertTrue(f.clean(True))
@@ -19,25 +18,25 @@ class BooleanFieldTest(SimpleTestCase):
self.assertTrue(f.clean(1))
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(0)
- self.assertTrue(f.clean('Django rocks'))
- self.assertTrue(f.clean('True'))
+ self.assertTrue(f.clean("Django rocks"))
+ self.assertTrue(f.clean("True"))
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('False')
+ f.clean("False")
def test_booleanfield_clean_2(self):
f = BooleanField(required=False)
- self.assertIs(f.clean(''), False)
+ self.assertIs(f.clean(""), False)
self.assertIs(f.clean(None), False)
self.assertIs(f.clean(True), True)
self.assertIs(f.clean(False), False)
self.assertIs(f.clean(1), True)
self.assertIs(f.clean(0), False)
- self.assertIs(f.clean('1'), True)
- self.assertIs(f.clean('0'), False)
- self.assertIs(f.clean('Django rocks'), True)
- self.assertIs(f.clean('False'), False)
- self.assertIs(f.clean('false'), False)
- self.assertIs(f.clean('FaLsE'), False)
+ self.assertIs(f.clean("1"), True)
+ self.assertIs(f.clean("0"), False)
+ self.assertIs(f.clean("Django rocks"), True)
+ self.assertIs(f.clean("False"), False)
+ self.assertIs(f.clean("false"), False)
+ self.assertIs(f.clean("FaLsE"), False)
def test_boolean_picklable(self):
self.assertIsInstance(pickle.loads(pickle.dumps(BooleanField())), BooleanField)
@@ -45,20 +44,20 @@ class BooleanFieldTest(SimpleTestCase):
def test_booleanfield_changed(self):
f = BooleanField()
self.assertFalse(f.has_changed(None, None))
- self.assertFalse(f.has_changed(None, ''))
- self.assertFalse(f.has_changed('', None))
- self.assertFalse(f.has_changed('', ''))
- self.assertTrue(f.has_changed(False, 'on'))
- self.assertFalse(f.has_changed(True, 'on'))
- self.assertTrue(f.has_changed(True, ''))
+ self.assertFalse(f.has_changed(None, ""))
+ self.assertFalse(f.has_changed("", None))
+ self.assertFalse(f.has_changed("", ""))
+ self.assertTrue(f.has_changed(False, "on"))
+ self.assertFalse(f.has_changed(True, "on"))
+ self.assertTrue(f.has_changed(True, ""))
# Initial value may have mutated to a string due to show_hidden_initial (#19537)
- self.assertTrue(f.has_changed('False', 'on'))
+ self.assertTrue(f.has_changed("False", "on"))
# HiddenInput widget sends string values for boolean but doesn't clean them in value_from_datadict
- self.assertFalse(f.has_changed(False, 'False'))
- self.assertFalse(f.has_changed(True, 'True'))
- self.assertTrue(f.has_changed(False, 'True'))
- self.assertTrue(f.has_changed(True, 'False'))
+ self.assertFalse(f.has_changed(False, "False"))
+ self.assertFalse(f.has_changed(True, "True"))
+ self.assertTrue(f.has_changed(False, "True"))
+ self.assertTrue(f.has_changed(True, "False"))
def test_disabled_has_changed(self):
f = BooleanField(disabled=True)
- self.assertIs(f.has_changed('True', 'False'), False)
+ self.assertIs(f.has_changed("True", "False"), False)
diff --git a/tests/forms_tests/field_tests/test_charfield.py b/tests/forms_tests/field_tests/test_charfield.py
index 352761deec..2c3f9b7ebe 100644
--- a/tests/forms_tests/field_tests/test_charfield.py
+++ b/tests/forms_tests/field_tests/test_charfield.py
@@ -1,66 +1,63 @@
from django.core.exceptions import ValidationError
-from django.forms import (
- CharField, HiddenInput, PasswordInput, Textarea, TextInput,
-)
+from django.forms import CharField, HiddenInput, PasswordInput, Textarea, TextInput
from django.test import SimpleTestCase
from . import FormFieldAssertionsMixin
class CharFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
-
def test_charfield_1(self):
f = CharField()
- self.assertEqual('1', f.clean(1))
- self.assertEqual('hello', f.clean('hello'))
+ self.assertEqual("1", f.clean(1))
+ self.assertEqual("hello", f.clean("hello"))
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(None)
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('')
- self.assertEqual('[1, 2, 3]', f.clean([1, 2, 3]))
+ f.clean("")
+ self.assertEqual("[1, 2, 3]", f.clean([1, 2, 3]))
self.assertIsNone(f.max_length)
self.assertIsNone(f.min_length)
def test_charfield_2(self):
f = CharField(required=False)
- self.assertEqual('1', f.clean(1))
- self.assertEqual('hello', f.clean('hello'))
- self.assertEqual('', f.clean(None))
- self.assertEqual('', f.clean(''))
- self.assertEqual('[1, 2, 3]', f.clean([1, 2, 3]))
+ self.assertEqual("1", f.clean(1))
+ self.assertEqual("hello", f.clean("hello"))
+ self.assertEqual("", f.clean(None))
+ self.assertEqual("", f.clean(""))
+ self.assertEqual("[1, 2, 3]", f.clean([1, 2, 3]))
self.assertIsNone(f.max_length)
self.assertIsNone(f.min_length)
def test_charfield_3(self):
f = CharField(max_length=10, required=False)
- self.assertEqual('12345', f.clean('12345'))
- self.assertEqual('1234567890', f.clean('1234567890'))
+ self.assertEqual("12345", f.clean("12345"))
+ self.assertEqual("1234567890", f.clean("1234567890"))
msg = "'Ensure this value has at most 10 characters (it has 11).'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('1234567890a')
+ f.clean("1234567890a")
self.assertEqual(f.max_length, 10)
self.assertIsNone(f.min_length)
def test_charfield_4(self):
f = CharField(min_length=10, required=False)
- self.assertEqual('', f.clean(''))
+ self.assertEqual("", f.clean(""))
msg = "'Ensure this value has at least 10 characters (it has 5).'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('12345')
- self.assertEqual('1234567890', f.clean('1234567890'))
- self.assertEqual('1234567890a', f.clean('1234567890a'))
+ f.clean("12345")
+ self.assertEqual("1234567890", f.clean("1234567890"))
+ self.assertEqual("1234567890a", f.clean("1234567890a"))
self.assertIsNone(f.max_length)
self.assertEqual(f.min_length, 10)
def test_charfield_5(self):
f = CharField(min_length=10, required=True)
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('')
+ f.clean("")
msg = "'Ensure this value has at least 10 characters (it has 5).'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('12345')
- self.assertEqual('1234567890', f.clean('1234567890'))
- self.assertEqual('1234567890a', f.clean('1234567890a'))
+ f.clean("12345")
+ self.assertEqual("1234567890", f.clean("1234567890"))
+ self.assertEqual("1234567890a", f.clean("1234567890a"))
self.assertIsNone(f.max_length)
self.assertEqual(f.min_length, 10)
@@ -70,12 +67,12 @@ class CharFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
raises an exception.
"""
with self.assertRaises(ValueError):
- CharField(min_length='a')
+ CharField(min_length="a")
with self.assertRaises(ValueError):
- CharField(max_length='a')
- msg = '__init__() takes 1 positional argument but 2 were given'
+ CharField(max_length="a")
+ msg = "__init__() takes 1 positional argument but 2 were given"
with self.assertRaisesMessage(TypeError, msg):
- CharField('a')
+ CharField("a")
def test_charfield_widget_attrs(self):
"""
@@ -90,22 +87,28 @@ class CharFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
# Return a maxlength attribute equal to max_length.
f = CharField(max_length=10)
- self.assertEqual(f.widget_attrs(TextInput()), {'maxlength': '10'})
- self.assertEqual(f.widget_attrs(PasswordInput()), {'maxlength': '10'})
- self.assertEqual(f.widget_attrs(Textarea()), {'maxlength': '10'})
+ self.assertEqual(f.widget_attrs(TextInput()), {"maxlength": "10"})
+ self.assertEqual(f.widget_attrs(PasswordInput()), {"maxlength": "10"})
+ self.assertEqual(f.widget_attrs(Textarea()), {"maxlength": "10"})
# Return a minlength attribute equal to min_length.
f = CharField(min_length=5)
- self.assertEqual(f.widget_attrs(TextInput()), {'minlength': '5'})
- self.assertEqual(f.widget_attrs(PasswordInput()), {'minlength': '5'})
- self.assertEqual(f.widget_attrs(Textarea()), {'minlength': '5'})
+ self.assertEqual(f.widget_attrs(TextInput()), {"minlength": "5"})
+ self.assertEqual(f.widget_attrs(PasswordInput()), {"minlength": "5"})
+ self.assertEqual(f.widget_attrs(Textarea()), {"minlength": "5"})
# Return both maxlength and minlength when both max_length and
# min_length are set.
f = CharField(max_length=10, min_length=5)
- self.assertEqual(f.widget_attrs(TextInput()), {'maxlength': '10', 'minlength': '5'})
- self.assertEqual(f.widget_attrs(PasswordInput()), {'maxlength': '10', 'minlength': '5'})
- self.assertEqual(f.widget_attrs(Textarea()), {'maxlength': '10', 'minlength': '5'})
+ self.assertEqual(
+ f.widget_attrs(TextInput()), {"maxlength": "10", "minlength": "5"}
+ )
+ self.assertEqual(
+ f.widget_attrs(PasswordInput()), {"maxlength": "10", "minlength": "5"}
+ )
+ self.assertEqual(
+ f.widget_attrs(Textarea()), {"maxlength": "10", "minlength": "5"}
+ )
self.assertEqual(f.widget_attrs(HiddenInput()), {})
def test_charfield_strip(self):
@@ -113,12 +116,12 @@ class CharFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
Values have whitespace stripped but not if strip=False.
"""
f = CharField()
- self.assertEqual(f.clean(' 1'), '1')
- self.assertEqual(f.clean('1 '), '1')
+ self.assertEqual(f.clean(" 1"), "1")
+ self.assertEqual(f.clean("1 "), "1")
f = CharField(strip=False)
- self.assertEqual(f.clean(' 1'), ' 1')
- self.assertEqual(f.clean('1 '), '1 ')
+ self.assertEqual(f.clean(" 1"), " 1")
+ self.assertEqual(f.clean("1 "), "1 ")
def test_strip_before_checking_empty(self):
"""
@@ -126,10 +129,11 @@ class CharFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
converted to the empty value, None.
"""
f = CharField(required=False, empty_value=None)
- self.assertIsNone(f.clean(' '))
+ self.assertIsNone(f.clean(" "))
def test_clean_non_string(self):
"""CharField.clean() calls str(value) before stripping it."""
+
class StringWrapper:
def __init__(self, v):
self.v = v
@@ -137,18 +141,20 @@ class CharFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
def __str__(self):
return self.v
- value = StringWrapper(' ')
+ value = StringWrapper(" ")
f1 = CharField(required=False, empty_value=None)
self.assertIsNone(f1.clean(value))
f2 = CharField(strip=False)
- self.assertEqual(f2.clean(value), ' ')
+ self.assertEqual(f2.clean(value), " ")
def test_charfield_disabled(self):
f = CharField(disabled=True)
- self.assertWidgetRendersTo(f, '<input type="text" name="f" id="id_f" disabled required>')
+ self.assertWidgetRendersTo(
+ f, '<input type="text" name="f" id="id_f" disabled required>'
+ )
def test_null_characters_prohibited(self):
f = CharField()
- msg = 'Null characters are not allowed.'
+ msg = "Null characters are not allowed."
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('\x00something')
+ f.clean("\x00something")
diff --git a/tests/forms_tests/field_tests/test_choicefield.py b/tests/forms_tests/field_tests/test_choicefield.py
index f25e2cedfd..bc580bbf02 100644
--- a/tests/forms_tests/field_tests/test_choicefield.py
+++ b/tests/forms_tests/field_tests/test_choicefield.py
@@ -7,52 +7,52 @@ from . import FormFieldAssertionsMixin
class ChoiceFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
-
def test_choicefield_1(self):
- f = ChoiceField(choices=[('1', 'One'), ('2', 'Two')])
+ f = ChoiceField(choices=[("1", "One"), ("2", "Two")])
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('')
+ f.clean("")
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(None)
- self.assertEqual('1', f.clean(1))
- self.assertEqual('1', f.clean('1'))
+ self.assertEqual("1", f.clean(1))
+ self.assertEqual("1", f.clean("1"))
msg = "'Select a valid choice. 3 is not one of the available choices.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('3')
+ f.clean("3")
def test_choicefield_2(self):
- f = ChoiceField(choices=[('1', 'One'), ('2', 'Two')], required=False)
- self.assertEqual('', f.clean(''))
- self.assertEqual('', f.clean(None))
- self.assertEqual('1', f.clean(1))
- self.assertEqual('1', f.clean('1'))
+ f = ChoiceField(choices=[("1", "One"), ("2", "Two")], required=False)
+ self.assertEqual("", f.clean(""))
+ self.assertEqual("", f.clean(None))
+ self.assertEqual("1", f.clean(1))
+ self.assertEqual("1", f.clean("1"))
msg = "'Select a valid choice. 3 is not one of the available choices.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('3')
+ f.clean("3")
def test_choicefield_3(self):
- f = ChoiceField(choices=[('J', 'John'), ('P', 'Paul')])
- self.assertEqual('J', f.clean('J'))
+ f = ChoiceField(choices=[("J", "John"), ("P", "Paul")])
+ self.assertEqual("J", f.clean("J"))
msg = "'Select a valid choice. John is not one of the available choices.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('John')
+ f.clean("John")
def test_choicefield_4(self):
f = ChoiceField(
choices=[
- ('Numbers', (('1', 'One'), ('2', 'Two'))),
- ('Letters', (('3', 'A'), ('4', 'B'))), ('5', 'Other'),
+ ("Numbers", (("1", "One"), ("2", "Two"))),
+ ("Letters", (("3", "A"), ("4", "B"))),
+ ("5", "Other"),
]
)
- self.assertEqual('1', f.clean(1))
- self.assertEqual('1', f.clean('1'))
- self.assertEqual('3', f.clean(3))
- self.assertEqual('3', f.clean('3'))
- self.assertEqual('5', f.clean(5))
- self.assertEqual('5', f.clean('5'))
+ self.assertEqual("1", f.clean(1))
+ self.assertEqual("1", f.clean("1"))
+ self.assertEqual("3", f.clean(3))
+ self.assertEqual("3", f.clean("3"))
+ self.assertEqual("5", f.clean(5))
+ self.assertEqual("5", f.clean("5"))
msg = "'Select a valid choice. 6 is not one of the available choices.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('6')
+ f.clean("6")
def test_choicefield_choices_default(self):
f = ChoiceField()
@@ -60,9 +60,10 @@ class ChoiceFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
def test_choicefield_callable(self):
def choices():
- return [('J', 'John'), ('P', 'Paul')]
+ return [("J", "John"), ("P", "Paul")]
+
f = ChoiceField(choices=choices)
- self.assertEqual('J', f.clean('J'))
+ self.assertEqual("J", f.clean("J"))
def test_choicefield_callable_may_evaluate_to_different_values(self):
choices = []
@@ -73,29 +74,29 @@ class ChoiceFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
class ChoiceFieldForm(Form):
choicefield = ChoiceField(choices=choices_as_callable)
- choices = [('J', 'John')]
+ choices = [("J", "John")]
form = ChoiceFieldForm()
- self.assertEqual([('J', 'John')], list(form.fields['choicefield'].choices))
+ self.assertEqual([("J", "John")], list(form.fields["choicefield"].choices))
- choices = [('P', 'Paul')]
+ choices = [("P", "Paul")]
form = ChoiceFieldForm()
- self.assertEqual([('P', 'Paul')], list(form.fields['choicefield'].choices))
+ self.assertEqual([("P", "Paul")], list(form.fields["choicefield"].choices))
def test_choicefield_disabled(self):
- f = ChoiceField(choices=[('J', 'John'), ('P', 'Paul')], disabled=True)
+ f = ChoiceField(choices=[("J", "John"), ("P", "Paul")], disabled=True)
self.assertWidgetRendersTo(
f,
'<select id="id_f" name="f" disabled><option value="J">John</option>'
- '<option value="P">Paul</option></select>'
+ '<option value="P">Paul</option></select>',
)
def test_choicefield_enumeration(self):
class FirstNames(models.TextChoices):
- JOHN = 'J', 'John'
- PAUL = 'P', 'Paul'
+ JOHN = "J", "John"
+ PAUL = "P", "Paul"
f = ChoiceField(choices=FirstNames.choices)
- self.assertEqual(f.clean('J'), 'J')
+ self.assertEqual(f.clean("J"), "J")
msg = "'Select a valid choice. 3 is not one of the available choices.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('3')
+ f.clean("3")
diff --git a/tests/forms_tests/field_tests/test_combofield.py b/tests/forms_tests/field_tests/test_combofield.py
index 481783fe2e..d433fdf2b3 100644
--- a/tests/forms_tests/field_tests/test_combofield.py
+++ b/tests/forms_tests/field_tests/test_combofield.py
@@ -4,25 +4,34 @@ from django.test import SimpleTestCase
class ComboFieldTest(SimpleTestCase):
-
def test_combofield_1(self):
f = ComboField(fields=[CharField(max_length=20), EmailField()])
- self.assertEqual('test@example.com', f.clean('test@example.com'))
- with self.assertRaisesMessage(ValidationError, "'Ensure this value has at most 20 characters (it has 28).'"):
- f.clean('longemailaddress@example.com')
- with self.assertRaisesMessage(ValidationError, "'Enter a valid email address.'"):
- f.clean('not an email')
+ self.assertEqual("test@example.com", f.clean("test@example.com"))
+ with self.assertRaisesMessage(
+ ValidationError,
+ "'Ensure this value has at most 20 characters (it has 28).'",
+ ):
+ f.clean("longemailaddress@example.com")
+ with self.assertRaisesMessage(
+ ValidationError, "'Enter a valid email address.'"
+ ):
+ f.clean("not an email")
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('')
+ f.clean("")
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(None)
def test_combofield_2(self):
f = ComboField(fields=[CharField(max_length=20), EmailField()], required=False)
- self.assertEqual('test@example.com', f.clean('test@example.com'))
- with self.assertRaisesMessage(ValidationError, "'Ensure this value has at most 20 characters (it has 28).'"):
- f.clean('longemailaddress@example.com')
- with self.assertRaisesMessage(ValidationError, "'Enter a valid email address.'"):
- f.clean('not an email')
- self.assertEqual('', f.clean(''))
- self.assertEqual('', f.clean(None))
+ self.assertEqual("test@example.com", f.clean("test@example.com"))
+ with self.assertRaisesMessage(
+ ValidationError,
+ "'Ensure this value has at most 20 characters (it has 28).'",
+ ):
+ f.clean("longemailaddress@example.com")
+ with self.assertRaisesMessage(
+ ValidationError, "'Enter a valid email address.'"
+ ):
+ f.clean("not an email")
+ self.assertEqual("", f.clean(""))
+ self.assertEqual("", f.clean(None))
diff --git a/tests/forms_tests/field_tests/test_datefield.py b/tests/forms_tests/field_tests/test_datefield.py
index 10d77bf1bb..a9f93f40ed 100644
--- a/tests/forms_tests/field_tests/test_datefield.py
+++ b/tests/forms_tests/field_tests/test_datefield.py
@@ -11,174 +11,195 @@ class GetDate(Form):
class DateFieldTest(SimpleTestCase):
-
def test_form_field(self):
- a = GetDate({'mydate_month': '4', 'mydate_day': '1', 'mydate_year': '2008'})
+ a = GetDate({"mydate_month": "4", "mydate_day": "1", "mydate_year": "2008"})
self.assertTrue(a.is_valid())
- self.assertEqual(a.cleaned_data['mydate'], date(2008, 4, 1))
+ self.assertEqual(a.cleaned_data["mydate"], date(2008, 4, 1))
# As with any widget that implements get_value_from_datadict(), we must
# accept the input from the "as_hidden" rendering as well.
self.assertHTMLEqual(
- a['mydate'].as_hidden(),
+ a["mydate"].as_hidden(),
'<input type="hidden" name="mydate" value="2008-04-01" id="id_mydate">',
)
- b = GetDate({'mydate': '2008-4-1'})
+ b = GetDate({"mydate": "2008-4-1"})
self.assertTrue(b.is_valid())
- self.assertEqual(b.cleaned_data['mydate'], date(2008, 4, 1))
+ self.assertEqual(b.cleaned_data["mydate"], date(2008, 4, 1))
# Invalid dates shouldn't be allowed
- c = GetDate({'mydate_month': '2', 'mydate_day': '31', 'mydate_year': '2010'})
+ c = GetDate({"mydate_month": "2", "mydate_day": "31", "mydate_year": "2010"})
self.assertFalse(c.is_valid())
- self.assertEqual(c.errors, {'mydate': ['Enter a valid date.']})
+ self.assertEqual(c.errors, {"mydate": ["Enter a valid date."]})
# label tag is correctly associated with month dropdown
- d = GetDate({'mydate_month': '1', 'mydate_day': '1', 'mydate_year': '2010'})
+ d = GetDate({"mydate_month": "1", "mydate_day": "1", "mydate_year": "2010"})
self.assertIn('<label for="id_mydate_month">', d.as_p())
- @translation.override('nl')
+ @translation.override("nl")
def test_l10n_date_changed(self):
"""
DateField.has_changed() with SelectDateWidget works with a localized
date format (#17165).
"""
# With Field.show_hidden_initial=False
- b = GetDate({
- 'mydate_year': '2008',
- 'mydate_month': '4',
- 'mydate_day': '1',
- }, initial={'mydate': date(2008, 4, 1)})
+ b = GetDate(
+ {
+ "mydate_year": "2008",
+ "mydate_month": "4",
+ "mydate_day": "1",
+ },
+ initial={"mydate": date(2008, 4, 1)},
+ )
self.assertFalse(b.has_changed())
- b = GetDate({
- 'mydate_year': '2008',
- 'mydate_month': '4',
- 'mydate_day': '2',
- }, initial={'mydate': date(2008, 4, 1)})
+ b = GetDate(
+ {
+ "mydate_year": "2008",
+ "mydate_month": "4",
+ "mydate_day": "2",
+ },
+ initial={"mydate": date(2008, 4, 1)},
+ )
self.assertTrue(b.has_changed())
# With Field.show_hidden_initial=True
class GetDateShowHiddenInitial(Form):
mydate = DateField(widget=SelectDateWidget, show_hidden_initial=True)
- b = GetDateShowHiddenInitial({
- 'mydate_year': '2008',
- 'mydate_month': '4',
- 'mydate_day': '1',
- 'initial-mydate': HiddenInput().format_value(date(2008, 4, 1)),
- }, initial={'mydate': date(2008, 4, 1)})
+ b = GetDateShowHiddenInitial(
+ {
+ "mydate_year": "2008",
+ "mydate_month": "4",
+ "mydate_day": "1",
+ "initial-mydate": HiddenInput().format_value(date(2008, 4, 1)),
+ },
+ initial={"mydate": date(2008, 4, 1)},
+ )
self.assertFalse(b.has_changed())
- b = GetDateShowHiddenInitial({
- 'mydate_year': '2008',
- 'mydate_month': '4',
- 'mydate_day': '22',
- 'initial-mydate': HiddenInput().format_value(date(2008, 4, 1)),
- }, initial={'mydate': date(2008, 4, 1)})
+ b = GetDateShowHiddenInitial(
+ {
+ "mydate_year": "2008",
+ "mydate_month": "4",
+ "mydate_day": "22",
+ "initial-mydate": HiddenInput().format_value(date(2008, 4, 1)),
+ },
+ initial={"mydate": date(2008, 4, 1)},
+ )
self.assertTrue(b.has_changed())
- b = GetDateShowHiddenInitial({
- 'mydate_year': '2008',
- 'mydate_month': '4',
- 'mydate_day': '22',
- 'initial-mydate': HiddenInput().format_value(date(2008, 4, 1)),
- }, initial={'mydate': date(2008, 4, 22)})
+ b = GetDateShowHiddenInitial(
+ {
+ "mydate_year": "2008",
+ "mydate_month": "4",
+ "mydate_day": "22",
+ "initial-mydate": HiddenInput().format_value(date(2008, 4, 1)),
+ },
+ initial={"mydate": date(2008, 4, 22)},
+ )
self.assertTrue(b.has_changed())
- b = GetDateShowHiddenInitial({
- 'mydate_year': '2008',
- 'mydate_month': '4',
- 'mydate_day': '22',
- 'initial-mydate': HiddenInput().format_value(date(2008, 4, 22)),
- }, initial={'mydate': date(2008, 4, 1)})
+ b = GetDateShowHiddenInitial(
+ {
+ "mydate_year": "2008",
+ "mydate_month": "4",
+ "mydate_day": "22",
+ "initial-mydate": HiddenInput().format_value(date(2008, 4, 22)),
+ },
+ initial={"mydate": date(2008, 4, 1)},
+ )
self.assertFalse(b.has_changed())
- @translation.override('nl')
+ @translation.override("nl")
def test_l10n_invalid_date_in(self):
# Invalid dates shouldn't be allowed
- a = GetDate({'mydate_month': '2', 'mydate_day': '31', 'mydate_year': '2010'})
+ a = GetDate({"mydate_month": "2", "mydate_day": "31", "mydate_year": "2010"})
self.assertFalse(a.is_valid())
# 'Geef een geldige datum op.' = 'Enter a valid date.'
- self.assertEqual(a.errors, {'mydate': ['Voer een geldige datum in.']})
+ self.assertEqual(a.errors, {"mydate": ["Voer een geldige datum in."]})
- @translation.override('nl')
+ @translation.override("nl")
def test_form_label_association(self):
# label tag is correctly associated with first rendered dropdown
- a = GetDate({'mydate_month': '1', 'mydate_day': '1', 'mydate_year': '2010'})
+ a = GetDate({"mydate_month": "1", "mydate_day": "1", "mydate_year": "2010"})
self.assertIn('<label for="id_mydate_day">', a.as_p())
def test_datefield_1(self):
f = DateField()
self.assertEqual(date(2006, 10, 25), f.clean(date(2006, 10, 25)))
self.assertEqual(date(2006, 10, 25), f.clean(datetime(2006, 10, 25, 14, 30)))
- self.assertEqual(date(2006, 10, 25), f.clean(datetime(2006, 10, 25, 14, 30, 59)))
- self.assertEqual(date(2006, 10, 25), f.clean(datetime(2006, 10, 25, 14, 30, 59, 200)))
- self.assertEqual(date(2006, 10, 25), f.clean('2006-10-25'))
- self.assertEqual(date(2006, 10, 25), f.clean('10/25/2006'))
- self.assertEqual(date(2006, 10, 25), f.clean('10/25/06'))
- self.assertEqual(date(2006, 10, 25), f.clean('Oct 25 2006'))
- self.assertEqual(date(2006, 10, 25), f.clean('October 25 2006'))
- self.assertEqual(date(2006, 10, 25), f.clean('October 25, 2006'))
- self.assertEqual(date(2006, 10, 25), f.clean('25 October 2006'))
- self.assertEqual(date(2006, 10, 25), f.clean('25 October, 2006'))
+ self.assertEqual(
+ date(2006, 10, 25), f.clean(datetime(2006, 10, 25, 14, 30, 59))
+ )
+ self.assertEqual(
+ date(2006, 10, 25), f.clean(datetime(2006, 10, 25, 14, 30, 59, 200))
+ )
+ self.assertEqual(date(2006, 10, 25), f.clean("2006-10-25"))
+ self.assertEqual(date(2006, 10, 25), f.clean("10/25/2006"))
+ self.assertEqual(date(2006, 10, 25), f.clean("10/25/06"))
+ self.assertEqual(date(2006, 10, 25), f.clean("Oct 25 2006"))
+ self.assertEqual(date(2006, 10, 25), f.clean("October 25 2006"))
+ self.assertEqual(date(2006, 10, 25), f.clean("October 25, 2006"))
+ self.assertEqual(date(2006, 10, 25), f.clean("25 October 2006"))
+ self.assertEqual(date(2006, 10, 25), f.clean("25 October, 2006"))
with self.assertRaisesMessage(ValidationError, "'Enter a valid date.'"):
- f.clean('2006-4-31')
+ f.clean("2006-4-31")
with self.assertRaisesMessage(ValidationError, "'Enter a valid date.'"):
- f.clean('200a-10-25')
+ f.clean("200a-10-25")
with self.assertRaisesMessage(ValidationError, "'Enter a valid date.'"):
- f.clean('25/10/06')
+ f.clean("25/10/06")
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(None)
def test_datefield_2(self):
f = DateField(required=False)
self.assertIsNone(f.clean(None))
- self.assertEqual('None', repr(f.clean(None)))
- self.assertIsNone(f.clean(''))
- self.assertEqual('None', repr(f.clean('')))
+ self.assertEqual("None", repr(f.clean(None)))
+ self.assertIsNone(f.clean(""))
+ self.assertEqual("None", repr(f.clean("")))
def test_datefield_3(self):
- f = DateField(input_formats=['%Y %m %d'])
+ f = DateField(input_formats=["%Y %m %d"])
self.assertEqual(date(2006, 10, 25), f.clean(date(2006, 10, 25)))
self.assertEqual(date(2006, 10, 25), f.clean(datetime(2006, 10, 25, 14, 30)))
- self.assertEqual(date(2006, 10, 25), f.clean('2006 10 25'))
+ self.assertEqual(date(2006, 10, 25), f.clean("2006 10 25"))
with self.assertRaisesMessage(ValidationError, "'Enter a valid date.'"):
- f.clean('2006-10-25')
+ f.clean("2006-10-25")
with self.assertRaisesMessage(ValidationError, "'Enter a valid date.'"):
- f.clean('10/25/2006')
+ f.clean("10/25/2006")
with self.assertRaisesMessage(ValidationError, "'Enter a valid date.'"):
- f.clean('10/25/06')
+ f.clean("10/25/06")
def test_datefield_4(self):
# Test whitespace stripping behavior (#5714)
f = DateField()
- self.assertEqual(date(2006, 10, 25), f.clean(' 10/25/2006 '))
- self.assertEqual(date(2006, 10, 25), f.clean(' 10/25/06 '))
- self.assertEqual(date(2006, 10, 25), f.clean(' Oct 25 2006 '))
- self.assertEqual(date(2006, 10, 25), f.clean(' October 25 2006 '))
- self.assertEqual(date(2006, 10, 25), f.clean(' October 25, 2006 '))
- self.assertEqual(date(2006, 10, 25), f.clean(' 25 October 2006 '))
+ self.assertEqual(date(2006, 10, 25), f.clean(" 10/25/2006 "))
+ self.assertEqual(date(2006, 10, 25), f.clean(" 10/25/06 "))
+ self.assertEqual(date(2006, 10, 25), f.clean(" Oct 25 2006 "))
+ self.assertEqual(date(2006, 10, 25), f.clean(" October 25 2006 "))
+ self.assertEqual(date(2006, 10, 25), f.clean(" October 25, 2006 "))
+ self.assertEqual(date(2006, 10, 25), f.clean(" 25 October 2006 "))
with self.assertRaisesMessage(ValidationError, "'Enter a valid date.'"):
- f.clean(' ')
+ f.clean(" ")
def test_datefield_5(self):
# Test null bytes (#18982)
f = DateField()
with self.assertRaisesMessage(ValidationError, "'Enter a valid date.'"):
- f.clean('a\x00b')
+ f.clean("a\x00b")
def test_datefield_changed(self):
- format = '%d/%m/%Y'
+ format = "%d/%m/%Y"
f = DateField(input_formats=[format])
d = date(2007, 9, 17)
- self.assertFalse(f.has_changed(d, '17/09/2007'))
+ self.assertFalse(f.has_changed(d, "17/09/2007"))
def test_datefield_strptime(self):
"""field.strptime() doesn't raise a UnicodeEncodeError (#16123)"""
f = DateField()
try:
- f.strptime('31 мая 2011', '%d-%b-%y')
+ f.strptime("31 мая 2011", "%d-%b-%y")
except Exception as e:
# assertIsInstance or assertRaises cannot be used because UnicodeEncodeError
# is a subclass of ValueError
diff --git a/tests/forms_tests/field_tests/test_datetimefield.py b/tests/forms_tests/field_tests/test_datetimefield.py
index 5d118cfdd2..3d266da6b7 100644
--- a/tests/forms_tests/field_tests/test_datetimefield.py
+++ b/tests/forms_tests/field_tests/test_datetimefield.py
@@ -7,7 +7,6 @@ from django.utils.timezone import get_fixed_timezone, utc
class DateTimeFieldTest(SimpleTestCase):
-
def test_datetimefield_clean(self):
tests = [
(date(2006, 10, 25), datetime(2006, 10, 25, 0, 0)),
@@ -17,48 +16,48 @@ class DateTimeFieldTest(SimpleTestCase):
datetime(2006, 10, 25, 14, 30, 59, 200),
datetime(2006, 10, 25, 14, 30, 59, 200),
),
- ('2006-10-25 14:30:45.000200', datetime(2006, 10, 25, 14, 30, 45, 200)),
- ('2006-10-25 14:30:45.0002', datetime(2006, 10, 25, 14, 30, 45, 200)),
- ('2006-10-25 14:30:45', datetime(2006, 10, 25, 14, 30, 45)),
- ('2006-10-25 14:30:00', datetime(2006, 10, 25, 14, 30)),
- ('2006-10-25 14:30', datetime(2006, 10, 25, 14, 30)),
- ('2006-10-25', datetime(2006, 10, 25, 0, 0)),
- ('10/25/2006 14:30:45.000200', datetime(2006, 10, 25, 14, 30, 45, 200)),
- ('10/25/2006 14:30:45', datetime(2006, 10, 25, 14, 30, 45)),
- ('10/25/2006 14:30:00', datetime(2006, 10, 25, 14, 30)),
- ('10/25/2006 14:30', datetime(2006, 10, 25, 14, 30)),
- ('10/25/2006', datetime(2006, 10, 25, 0, 0)),
- ('10/25/06 14:30:45.000200', datetime(2006, 10, 25, 14, 30, 45, 200)),
- ('10/25/06 14:30:45', datetime(2006, 10, 25, 14, 30, 45)),
- ('10/25/06 14:30:00', datetime(2006, 10, 25, 14, 30)),
- ('10/25/06 14:30', datetime(2006, 10, 25, 14, 30)),
- ('10/25/06', datetime(2006, 10, 25, 0, 0)),
+ ("2006-10-25 14:30:45.000200", datetime(2006, 10, 25, 14, 30, 45, 200)),
+ ("2006-10-25 14:30:45.0002", datetime(2006, 10, 25, 14, 30, 45, 200)),
+ ("2006-10-25 14:30:45", datetime(2006, 10, 25, 14, 30, 45)),
+ ("2006-10-25 14:30:00", datetime(2006, 10, 25, 14, 30)),
+ ("2006-10-25 14:30", datetime(2006, 10, 25, 14, 30)),
+ ("2006-10-25", datetime(2006, 10, 25, 0, 0)),
+ ("10/25/2006 14:30:45.000200", datetime(2006, 10, 25, 14, 30, 45, 200)),
+ ("10/25/2006 14:30:45", datetime(2006, 10, 25, 14, 30, 45)),
+ ("10/25/2006 14:30:00", datetime(2006, 10, 25, 14, 30)),
+ ("10/25/2006 14:30", datetime(2006, 10, 25, 14, 30)),
+ ("10/25/2006", datetime(2006, 10, 25, 0, 0)),
+ ("10/25/06 14:30:45.000200", datetime(2006, 10, 25, 14, 30, 45, 200)),
+ ("10/25/06 14:30:45", datetime(2006, 10, 25, 14, 30, 45)),
+ ("10/25/06 14:30:00", datetime(2006, 10, 25, 14, 30)),
+ ("10/25/06 14:30", datetime(2006, 10, 25, 14, 30)),
+ ("10/25/06", datetime(2006, 10, 25, 0, 0)),
# ISO 8601 formats.
(
- '2014-09-23T22:34:41.614804',
+ "2014-09-23T22:34:41.614804",
datetime(2014, 9, 23, 22, 34, 41, 614804),
),
- ('2014-09-23T22:34:41', datetime(2014, 9, 23, 22, 34, 41)),
- ('2014-09-23T22:34', datetime(2014, 9, 23, 22, 34)),
- ('2014-09-23', datetime(2014, 9, 23, 0, 0)),
- ('2014-09-23T22:34Z', datetime(2014, 9, 23, 22, 34, tzinfo=utc)),
+ ("2014-09-23T22:34:41", datetime(2014, 9, 23, 22, 34, 41)),
+ ("2014-09-23T22:34", datetime(2014, 9, 23, 22, 34)),
+ ("2014-09-23", datetime(2014, 9, 23, 0, 0)),
+ ("2014-09-23T22:34Z", datetime(2014, 9, 23, 22, 34, tzinfo=utc)),
(
- '2014-09-23T22:34+07:00',
+ "2014-09-23T22:34+07:00",
datetime(2014, 9, 23, 22, 34, tzinfo=get_fixed_timezone(420)),
),
# Whitespace stripping.
- (' 2006-10-25 14:30:45 ', datetime(2006, 10, 25, 14, 30, 45)),
- (' 2006-10-25 ', datetime(2006, 10, 25, 0, 0)),
- (' 10/25/2006 14:30:45 ', datetime(2006, 10, 25, 14, 30, 45)),
- (' 10/25/2006 14:30 ', datetime(2006, 10, 25, 14, 30)),
- (' 10/25/2006 ', datetime(2006, 10, 25, 0, 0)),
- (' 10/25/06 14:30:45 ', datetime(2006, 10, 25, 14, 30, 45)),
- (' 10/25/06 ', datetime(2006, 10, 25, 0, 0)),
+ (" 2006-10-25 14:30:45 ", datetime(2006, 10, 25, 14, 30, 45)),
+ (" 2006-10-25 ", datetime(2006, 10, 25, 0, 0)),
+ (" 10/25/2006 14:30:45 ", datetime(2006, 10, 25, 14, 30, 45)),
+ (" 10/25/2006 14:30 ", datetime(2006, 10, 25, 14, 30)),
+ (" 10/25/2006 ", datetime(2006, 10, 25, 0, 0)),
+ (" 10/25/06 14:30:45 ", datetime(2006, 10, 25, 14, 30, 45)),
+ (" 10/25/06 ", datetime(2006, 10, 25, 0, 0)),
(
- ' 2014-09-23T22:34:41.614804 ',
+ " 2014-09-23T22:34:41.614804 ",
datetime(2014, 9, 23, 22, 34, 41, 614804),
),
- (' 2014-09-23T22:34Z ', datetime(2014, 9, 23, 22, 34, tzinfo=utc)),
+ (" 2014-09-23T22:34Z ", datetime(2014, 9, 23, 22, 34, tzinfo=utc)),
]
f = DateTimeField()
for value, expected_datetime in tests:
@@ -69,40 +68,46 @@ class DateTimeFieldTest(SimpleTestCase):
f = DateTimeField()
msg = "'Enter a valid date/time.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('hello')
+ f.clean("hello")
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('2006-10-25 4:30 p.m.')
+ f.clean("2006-10-25 4:30 p.m.")
with self.assertRaisesMessage(ValidationError, msg):
- f.clean(' ')
+ f.clean(" ")
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('2014-09-23T28:23')
- f = DateTimeField(input_formats=['%Y %m %d %I:%M %p'])
+ f.clean("2014-09-23T28:23")
+ f = DateTimeField(input_formats=["%Y %m %d %I:%M %p"])
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('2006.10.25 14:30:45')
+ f.clean("2006.10.25 14:30:45")
def test_datetimefield_clean_input_formats(self):
tests = [
- ('%Y %m %d %I:%M %p', (
- (date(2006, 10, 25), datetime(2006, 10, 25, 0, 0)),
- (datetime(2006, 10, 25, 14, 30), datetime(2006, 10, 25, 14, 30)),
- (
- datetime(2006, 10, 25, 14, 30, 59),
- datetime(2006, 10, 25, 14, 30, 59),
- ),
+ (
+ "%Y %m %d %I:%M %p",
(
- datetime(2006, 10, 25, 14, 30, 59, 200),
- datetime(2006, 10, 25, 14, 30, 59, 200),
+ (date(2006, 10, 25), datetime(2006, 10, 25, 0, 0)),
+ (datetime(2006, 10, 25, 14, 30), datetime(2006, 10, 25, 14, 30)),
+ (
+ datetime(2006, 10, 25, 14, 30, 59),
+ datetime(2006, 10, 25, 14, 30, 59),
+ ),
+ (
+ datetime(2006, 10, 25, 14, 30, 59, 200),
+ datetime(2006, 10, 25, 14, 30, 59, 200),
+ ),
+ ("2006 10 25 2:30 PM", datetime(2006, 10, 25, 14, 30)),
+ # ISO-like formats are always accepted.
+ ("2006-10-25 14:30:45", datetime(2006, 10, 25, 14, 30, 45)),
),
- ('2006 10 25 2:30 PM', datetime(2006, 10, 25, 14, 30)),
- # ISO-like formats are always accepted.
- ('2006-10-25 14:30:45', datetime(2006, 10, 25, 14, 30, 45)),
- )),
- ('%Y.%m.%d %H:%M:%S.%f', (
+ ),
+ (
+ "%Y.%m.%d %H:%M:%S.%f",
(
- '2006.10.25 14:30:45.0002',
- datetime(2006, 10, 25, 14, 30, 45, 200),
+ (
+ "2006.10.25 14:30:45.0002",
+ datetime(2006, 10, 25, 14, 30, 45, 200),
+ ),
),
- )),
+ ),
]
for input_format, values in tests:
f = DateTimeField(input_formats=[input_format])
@@ -113,11 +118,11 @@ class DateTimeFieldTest(SimpleTestCase):
def test_datetimefield_not_required(self):
f = DateTimeField(required=False)
self.assertIsNone(f.clean(None))
- self.assertEqual('None', repr(f.clean(None)))
- self.assertIsNone(f.clean(''))
- self.assertEqual('None', repr(f.clean('')))
+ self.assertEqual("None", repr(f.clean(None)))
+ self.assertIsNone(f.clean(""))
+ self.assertEqual("None", repr(f.clean("")))
def test_datetimefield_changed(self):
- f = DateTimeField(input_formats=['%Y %m %d %I:%M %p'])
+ f = DateTimeField(input_formats=["%Y %m %d %I:%M %p"])
d = datetime(2006, 9, 17, 14, 30, 0)
- self.assertFalse(f.has_changed(d, '2006 09 17 2:30 PM'))
+ self.assertFalse(f.has_changed(d, "2006 09 17 2:30 PM"))
diff --git a/tests/forms_tests/field_tests/test_decimalfield.py b/tests/forms_tests/field_tests/test_decimalfield.py
index 1dd0984ac7..6e49a41341 100644
--- a/tests/forms_tests/field_tests/test_decimalfield.py
+++ b/tests/forms_tests/field_tests/test_decimalfield.py
@@ -10,40 +10,51 @@ from . import FormFieldAssertionsMixin
class DecimalFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
-
def test_decimalfield_1(self):
f = DecimalField(max_digits=4, decimal_places=2)
- self.assertWidgetRendersTo(f, '<input id="id_f" step="0.01" type="number" name="f" required>')
+ self.assertWidgetRendersTo(
+ f, '<input id="id_f" step="0.01" type="number" name="f" required>'
+ )
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('')
+ f.clean("")
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(None)
- self.assertEqual(f.clean('1'), decimal.Decimal("1"))
- self.assertIsInstance(f.clean('1'), decimal.Decimal)
- self.assertEqual(f.clean('23'), decimal.Decimal("23"))
- self.assertEqual(f.clean('3.14'), decimal.Decimal("3.14"))
+ self.assertEqual(f.clean("1"), decimal.Decimal("1"))
+ self.assertIsInstance(f.clean("1"), decimal.Decimal)
+ self.assertEqual(f.clean("23"), decimal.Decimal("23"))
+ self.assertEqual(f.clean("3.14"), decimal.Decimal("3.14"))
self.assertEqual(f.clean(3.14), decimal.Decimal("3.14"))
- self.assertEqual(f.clean(decimal.Decimal('3.14')), decimal.Decimal("3.14"))
- self.assertEqual(f.clean('1.0 '), decimal.Decimal("1.0"))
- self.assertEqual(f.clean(' 1.0'), decimal.Decimal("1.0"))
- self.assertEqual(f.clean(' 1.0 '), decimal.Decimal("1.0"))
- with self.assertRaisesMessage(ValidationError, "'Ensure that there are no more than 4 digits in total.'"):
- f.clean('123.45')
- with self.assertRaisesMessage(ValidationError, "'Ensure that there are no more than 2 decimal places.'"):
- f.clean('1.234')
+ self.assertEqual(f.clean(decimal.Decimal("3.14")), decimal.Decimal("3.14"))
+ self.assertEqual(f.clean("1.0 "), decimal.Decimal("1.0"))
+ self.assertEqual(f.clean(" 1.0"), decimal.Decimal("1.0"))
+ self.assertEqual(f.clean(" 1.0 "), decimal.Decimal("1.0"))
+ with self.assertRaisesMessage(
+ ValidationError, "'Ensure that there are no more than 4 digits in total.'"
+ ):
+ f.clean("123.45")
+ with self.assertRaisesMessage(
+ ValidationError, "'Ensure that there are no more than 2 decimal places.'"
+ ):
+ f.clean("1.234")
msg = "'Ensure that there are no more than 2 digits before the decimal point.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('123.4')
- self.assertEqual(f.clean('-12.34'), decimal.Decimal("-12.34"))
- with self.assertRaisesMessage(ValidationError, "'Ensure that there are no more than 4 digits in total.'"):
- f.clean('-123.45')
- self.assertEqual(f.clean('-.12'), decimal.Decimal("-0.12"))
- self.assertEqual(f.clean('-00.12'), decimal.Decimal("-0.12"))
- self.assertEqual(f.clean('-000.12'), decimal.Decimal("-0.12"))
- with self.assertRaisesMessage(ValidationError, "'Ensure that there are no more than 2 decimal places.'"):
- f.clean('-000.123')
- with self.assertRaisesMessage(ValidationError, "'Ensure that there are no more than 4 digits in total.'"):
- f.clean('-000.12345')
+ f.clean("123.4")
+ self.assertEqual(f.clean("-12.34"), decimal.Decimal("-12.34"))
+ with self.assertRaisesMessage(
+ ValidationError, "'Ensure that there are no more than 4 digits in total.'"
+ ):
+ f.clean("-123.45")
+ self.assertEqual(f.clean("-.12"), decimal.Decimal("-0.12"))
+ self.assertEqual(f.clean("-00.12"), decimal.Decimal("-0.12"))
+ self.assertEqual(f.clean("-000.12"), decimal.Decimal("-0.12"))
+ with self.assertRaisesMessage(
+ ValidationError, "'Ensure that there are no more than 2 decimal places.'"
+ ):
+ f.clean("-000.123")
+ with self.assertRaisesMessage(
+ ValidationError, "'Ensure that there are no more than 4 digits in total.'"
+ ):
+ f.clean("-000.12345")
self.assertEqual(f.max_digits, 4)
self.assertEqual(f.decimal_places, 2)
self.assertIsNone(f.max_value)
@@ -52,21 +63,34 @@ class DecimalFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
def test_enter_a_number_error(self):
f = DecimalField(max_value=1, max_digits=4, decimal_places=2)
values = (
- '-NaN', 'NaN', '+NaN',
- '-sNaN', 'sNaN', '+sNaN',
- '-Inf', 'Inf', '+Inf',
- '-Infinity', 'Infinity', '+Infinity',
- 'a', 'łąść', '1.0a', '--0.12',
+ "-NaN",
+ "NaN",
+ "+NaN",
+ "-sNaN",
+ "sNaN",
+ "+sNaN",
+ "-Inf",
+ "Inf",
+ "+Inf",
+ "-Infinity",
+ "Infinity",
+ "+Infinity",
+ "a",
+ "łąść",
+ "1.0a",
+ "--0.12",
)
for value in values:
- with self.subTest(value=value), self.assertRaisesMessage(ValidationError, "'Enter a number.'"):
+ with self.subTest(value=value), self.assertRaisesMessage(
+ ValidationError, "'Enter a number.'"
+ ):
f.clean(value)
def test_decimalfield_2(self):
f = DecimalField(max_digits=4, decimal_places=2, required=False)
- self.assertIsNone(f.clean(''))
+ self.assertIsNone(f.clean(""))
self.assertIsNone(f.clean(None))
- self.assertEqual(f.clean('1'), decimal.Decimal("1"))
+ self.assertEqual(f.clean("1"), decimal.Decimal("1"))
self.assertEqual(f.max_digits, 4)
self.assertEqual(f.decimal_places, 2)
self.assertIsNone(f.max_value)
@@ -74,71 +98,82 @@ class DecimalFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
def test_decimalfield_3(self):
f = DecimalField(
- max_digits=4, decimal_places=2,
- max_value=decimal.Decimal('1.5'),
- min_value=decimal.Decimal('0.5')
+ max_digits=4,
+ decimal_places=2,
+ max_value=decimal.Decimal("1.5"),
+ min_value=decimal.Decimal("0.5"),
)
self.assertWidgetRendersTo(
f,
'<input step="0.01" name="f" min="0.5" max="1.5" type="number" id="id_f" required>',
)
- with self.assertRaisesMessage(ValidationError, "'Ensure this value is less than or equal to 1.5.'"):
- f.clean('1.6')
- with self.assertRaisesMessage(ValidationError, "'Ensure this value is greater than or equal to 0.5.'"):
- f.clean('0.4')
- self.assertEqual(f.clean('1.5'), decimal.Decimal("1.5"))
- self.assertEqual(f.clean('0.5'), decimal.Decimal("0.5"))
- self.assertEqual(f.clean('.5'), decimal.Decimal("0.5"))
- self.assertEqual(f.clean('00.50'), decimal.Decimal("0.50"))
+ with self.assertRaisesMessage(
+ ValidationError, "'Ensure this value is less than or equal to 1.5.'"
+ ):
+ f.clean("1.6")
+ with self.assertRaisesMessage(
+ ValidationError, "'Ensure this value is greater than or equal to 0.5.'"
+ ):
+ f.clean("0.4")
+ self.assertEqual(f.clean("1.5"), decimal.Decimal("1.5"))
+ self.assertEqual(f.clean("0.5"), decimal.Decimal("0.5"))
+ self.assertEqual(f.clean(".5"), decimal.Decimal("0.5"))
+ self.assertEqual(f.clean("00.50"), decimal.Decimal("0.50"))
self.assertEqual(f.max_digits, 4)
self.assertEqual(f.decimal_places, 2)
- self.assertEqual(f.max_value, decimal.Decimal('1.5'))
- self.assertEqual(f.min_value, decimal.Decimal('0.5'))
+ self.assertEqual(f.max_value, decimal.Decimal("1.5"))
+ self.assertEqual(f.min_value, decimal.Decimal("0.5"))
def test_decimalfield_4(self):
f = DecimalField(decimal_places=2)
- with self.assertRaisesMessage(ValidationError, "'Ensure that there are no more than 2 decimal places.'"):
- f.clean('0.00000001')
+ with self.assertRaisesMessage(
+ ValidationError, "'Ensure that there are no more than 2 decimal places.'"
+ ):
+ f.clean("0.00000001")
def test_decimalfield_5(self):
f = DecimalField(max_digits=3)
# Leading whole zeros "collapse" to one digit.
- self.assertEqual(f.clean('0000000.10'), decimal.Decimal("0.1"))
+ self.assertEqual(f.clean("0000000.10"), decimal.Decimal("0.1"))
# But a leading 0 before the . doesn't count toward max_digits
- self.assertEqual(f.clean('0000000.100'), decimal.Decimal("0.100"))
+ self.assertEqual(f.clean("0000000.100"), decimal.Decimal("0.100"))
# Only leading whole zeros "collapse" to one digit.
- self.assertEqual(f.clean('000000.02'), decimal.Decimal('0.02'))
- with self.assertRaisesMessage(ValidationError, "'Ensure that there are no more than 3 digits in total.'"):
- f.clean('000000.0002')
- self.assertEqual(f.clean('.002'), decimal.Decimal("0.002"))
+ self.assertEqual(f.clean("000000.02"), decimal.Decimal("0.02"))
+ with self.assertRaisesMessage(
+ ValidationError, "'Ensure that there are no more than 3 digits in total.'"
+ ):
+ f.clean("000000.0002")
+ self.assertEqual(f.clean(".002"), decimal.Decimal("0.002"))
def test_decimalfield_6(self):
f = DecimalField(max_digits=2, decimal_places=2)
- self.assertEqual(f.clean('.01'), decimal.Decimal(".01"))
+ self.assertEqual(f.clean(".01"), decimal.Decimal(".01"))
msg = "'Ensure that there are no more than 0 digits before the decimal point.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('1.1')
+ f.clean("1.1")
def test_decimalfield_scientific(self):
f = DecimalField(max_digits=4, decimal_places=2)
with self.assertRaisesMessage(ValidationError, "Ensure that there are no more"):
- f.clean('1E+2')
- self.assertEqual(f.clean('1E+1'), decimal.Decimal('10'))
- self.assertEqual(f.clean('1E-1'), decimal.Decimal('0.1'))
- self.assertEqual(f.clean('0.546e+2'), decimal.Decimal('54.6'))
+ f.clean("1E+2")
+ self.assertEqual(f.clean("1E+1"), decimal.Decimal("10"))
+ self.assertEqual(f.clean("1E-1"), decimal.Decimal("0.1"))
+ self.assertEqual(f.clean("0.546e+2"), decimal.Decimal("54.6"))
def test_decimalfield_widget_attrs(self):
f = DecimalField(max_digits=6, decimal_places=2)
self.assertEqual(f.widget_attrs(Widget()), {})
- self.assertEqual(f.widget_attrs(NumberInput()), {'step': '0.01'})
+ self.assertEqual(f.widget_attrs(NumberInput()), {"step": "0.01"})
f = DecimalField(max_digits=10, decimal_places=0)
- self.assertEqual(f.widget_attrs(NumberInput()), {'step': '1'})
+ self.assertEqual(f.widget_attrs(NumberInput()), {"step": "1"})
f = DecimalField(max_digits=19, decimal_places=19)
- self.assertEqual(f.widget_attrs(NumberInput()), {'step': '1e-19'})
+ self.assertEqual(f.widget_attrs(NumberInput()), {"step": "1e-19"})
f = DecimalField(max_digits=20)
- self.assertEqual(f.widget_attrs(NumberInput()), {'step': 'any'})
- f = DecimalField(max_digits=6, widget=NumberInput(attrs={'step': '0.01'}))
- self.assertWidgetRendersTo(f, '<input step="0.01" name="f" type="number" id="id_f" required>')
+ self.assertEqual(f.widget_attrs(NumberInput()), {"step": "any"})
+ f = DecimalField(max_digits=6, widget=NumberInput(attrs={"step": "0.01"}))
+ self.assertWidgetRendersTo(
+ f, '<input step="0.01" name="f" type="number" id="id_f" required>'
+ )
def test_decimalfield_localized(self):
"""
@@ -151,10 +186,10 @@ class DecimalFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
def test_decimalfield_changed(self):
f = DecimalField(max_digits=2, decimal_places=2)
d = decimal.Decimal("0.1")
- self.assertFalse(f.has_changed(d, '0.10'))
- self.assertTrue(f.has_changed(d, '0.101'))
+ self.assertFalse(f.has_changed(d, "0.10"))
+ self.assertTrue(f.has_changed(d, "0.101"))
- with translation.override('fr'):
+ with translation.override("fr"):
f = DecimalField(max_digits=2, decimal_places=2, localize=True)
localized_d = formats.localize_input(d) # -> '0,1' in French
self.assertFalse(f.has_changed(d, localized_d))
@@ -164,22 +199,26 @@ class DecimalFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
# format-related settings will take precedence over locale-dictated
# formats.
@ignore_warnings(category=RemovedInDjango50Warning)
- @override_settings(USE_L10N=False, DECIMAL_SEPARATOR=',')
+ @override_settings(USE_L10N=False, DECIMAL_SEPARATOR=",")
def test_decimalfield_support_decimal_separator(self):
f = DecimalField(localize=True)
- self.assertEqual(f.clean('1001,10'), decimal.Decimal("1001.10"))
- self.assertEqual(f.clean('1001.10'), decimal.Decimal("1001.10"))
+ self.assertEqual(f.clean("1001,10"), decimal.Decimal("1001.10"))
+ self.assertEqual(f.clean("1001.10"), decimal.Decimal("1001.10"))
# RemovedInDjango50Warning: When the deprecation ends, remove
# @ignore_warnings and USE_L10N=False. The test should remain because
# format-related settings will take precedence over locale-dictated
# formats.
@ignore_warnings(category=RemovedInDjango50Warning)
- @override_settings(USE_L10N=False, DECIMAL_SEPARATOR=',', USE_THOUSAND_SEPARATOR=True,
- THOUSAND_SEPARATOR='.')
+ @override_settings(
+ USE_L10N=False,
+ DECIMAL_SEPARATOR=",",
+ USE_THOUSAND_SEPARATOR=True,
+ THOUSAND_SEPARATOR=".",
+ )
def test_decimalfield_support_thousands_separator(self):
f = DecimalField(localize=True)
- self.assertEqual(f.clean('1.001,10'), decimal.Decimal("1001.10"))
+ self.assertEqual(f.clean("1.001,10"), decimal.Decimal("1001.10"))
msg = "'Enter a number.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('1,001.1')
+ f.clean("1,001.1")
diff --git a/tests/forms_tests/field_tests/test_durationfield.py b/tests/forms_tests/field_tests/test_durationfield.py
index dae139446d..834638354c 100644
--- a/tests/forms_tests/field_tests/test_durationfield.py
+++ b/tests/forms_tests/field_tests/test_durationfield.py
@@ -10,32 +10,35 @@ from . import FormFieldAssertionsMixin
class DurationFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
-
def test_durationfield_clean(self):
f = DurationField()
- self.assertEqual(datetime.timedelta(seconds=30), f.clean('30'))
- self.assertEqual(datetime.timedelta(minutes=15, seconds=30), f.clean('15:30'))
- self.assertEqual(datetime.timedelta(hours=1, minutes=15, seconds=30), f.clean('1:15:30'))
+ self.assertEqual(datetime.timedelta(seconds=30), f.clean("30"))
+ self.assertEqual(datetime.timedelta(minutes=15, seconds=30), f.clean("15:30"))
+ self.assertEqual(
+ datetime.timedelta(hours=1, minutes=15, seconds=30), f.clean("1:15:30")
+ )
self.assertEqual(
- datetime.timedelta(days=1, hours=1, minutes=15, seconds=30, milliseconds=300),
- f.clean('1 1:15:30.3')
+ datetime.timedelta(
+ days=1, hours=1, minutes=15, seconds=30, milliseconds=300
+ ),
+ f.clean("1 1:15:30.3"),
)
self.assertEqual(
datetime.timedelta(0, 10800),
f.clean(datetime.timedelta(0, 10800)),
)
- msg = 'This field is required.'
+ msg = "This field is required."
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('')
- msg = 'Enter a valid duration.'
+ f.clean("")
+ msg = "Enter a valid duration."
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('not_a_time')
+ f.clean("not_a_time")
with self.assertRaisesMessage(ValidationError, msg):
- DurationField().clean('P3(3D')
+ DurationField().clean("P3(3D")
def test_durationfield_clean_not_required(self):
f = DurationField(required=False)
- self.assertIsNone(f.clean(''))
+ self.assertIsNone(f.clean(""))
def test_overflow(self):
msg = "The number of days must be between {min_days} and {max_days}.".format(
@@ -44,18 +47,18 @@ class DurationFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
)
f = DurationField()
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('1000000000 00:00:00')
+ f.clean("1000000000 00:00:00")
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('-1000000000 00:00:00')
+ f.clean("-1000000000 00:00:00")
def test_overflow_translation(self):
msg = "Le nombre de jours doit être entre {min_days} et {max_days}.".format(
min_days=datetime.timedelta.min.days,
max_days=datetime.timedelta.max.days,
)
- with translation.override('fr'):
+ with translation.override("fr"):
with self.assertRaisesMessage(ValidationError, msg):
- DurationField().clean('1000000000 00:00:00')
+ DurationField().clean("1000000000 00:00:00")
def test_durationfield_render(self):
self.assertWidgetRendersTo(
@@ -71,5 +74,5 @@ class DurationFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
field = DurationField()
td = datetime.timedelta(minutes=15, seconds=30)
self.assertEqual(field.prepare_value(td), duration_string(td))
- self.assertEqual(field.prepare_value('arbitrary'), 'arbitrary')
+ self.assertEqual(field.prepare_value("arbitrary"), "arbitrary")
self.assertIsNone(field.prepare_value(None))
diff --git a/tests/forms_tests/field_tests/test_emailfield.py b/tests/forms_tests/field_tests/test_emailfield.py
index 8b85e4dcc1..d1d52dd608 100644
--- a/tests/forms_tests/field_tests/test_emailfield.py
+++ b/tests/forms_tests/field_tests/test_emailfield.py
@@ -6,37 +6,44 @@ from . import FormFieldAssertionsMixin
class EmailFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
-
def test_emailfield_1(self):
f = EmailField()
- self.assertWidgetRendersTo(f, '<input type="email" name="f" id="id_f" required>')
+ self.assertWidgetRendersTo(
+ f, '<input type="email" name="f" id="id_f" required>'
+ )
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('')
+ f.clean("")
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(None)
- self.assertEqual('person@example.com', f.clean('person@example.com'))
- with self.assertRaisesMessage(ValidationError, "'Enter a valid email address.'"):
- f.clean('foo')
+ self.assertEqual("person@example.com", f.clean("person@example.com"))
+ with self.assertRaisesMessage(
+ ValidationError, "'Enter a valid email address.'"
+ ):
+ f.clean("foo")
self.assertEqual(
- 'local@domain.with.idn.xyz\xe4\xf6\xfc\xdfabc.part.com',
- f.clean('local@domain.with.idn.xyzäöüßabc.part.com')
+ "local@domain.with.idn.xyz\xe4\xf6\xfc\xdfabc.part.com",
+ f.clean("local@domain.with.idn.xyzäöüßabc.part.com"),
)
def test_email_regexp_for_performance(self):
f = EmailField()
# Check for runaway regex security problem. This will take a long time
# if the security fix isn't in place.
- addr = 'viewx3dtextx26qx3d@yahoo.comx26latlngx3d15854521645943074058'
+ addr = "viewx3dtextx26qx3d@yahoo.comx26latlngx3d15854521645943074058"
self.assertEqual(addr, f.clean(addr))
def test_emailfield_not_required(self):
f = EmailField(required=False)
- self.assertEqual('', f.clean(''))
- self.assertEqual('', f.clean(None))
- self.assertEqual('person@example.com', f.clean('person@example.com'))
- self.assertEqual('example@example.com', f.clean(' example@example.com \t \t '))
- with self.assertRaisesMessage(ValidationError, "'Enter a valid email address.'"):
- f.clean('foo')
+ self.assertEqual("", f.clean(""))
+ self.assertEqual("", f.clean(None))
+ self.assertEqual("person@example.com", f.clean("person@example.com"))
+ self.assertEqual(
+ "example@example.com", f.clean(" example@example.com \t \t ")
+ )
+ with self.assertRaisesMessage(
+ ValidationError, "'Enter a valid email address.'"
+ ):
+ f.clean("foo")
def test_emailfield_min_max_length(self):
f = EmailField(min_length=10, max_length=15)
@@ -44,15 +51,21 @@ class EmailFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
f,
'<input id="id_f" type="email" name="f" maxlength="15" minlength="10" required>',
)
- with self.assertRaisesMessage(ValidationError, "'Ensure this value has at least 10 characters (it has 9).'"):
- f.clean('a@foo.com')
- self.assertEqual('alf@foo.com', f.clean('alf@foo.com'))
- with self.assertRaisesMessage(ValidationError, "'Ensure this value has at most 15 characters (it has 20).'"):
- f.clean('alf123456788@foo.com')
+ with self.assertRaisesMessage(
+ ValidationError,
+ "'Ensure this value has at least 10 characters (it has 9).'",
+ ):
+ f.clean("a@foo.com")
+ self.assertEqual("alf@foo.com", f.clean("alf@foo.com"))
+ with self.assertRaisesMessage(
+ ValidationError,
+ "'Ensure this value has at most 15 characters (it has 20).'",
+ ):
+ f.clean("alf123456788@foo.com")
def test_emailfield_strip_on_none_value(self):
f = EmailField(required=False, empty_value=None)
- self.assertIsNone(f.clean(''))
+ self.assertIsNone(f.clean(""))
self.assertIsNone(f.clean(None))
def test_emailfield_unable_to_set_strip_kwarg(self):
diff --git a/tests/forms_tests/field_tests/test_filefield.py b/tests/forms_tests/field_tests/test_filefield.py
index 2db106e4a0..56aaa311e0 100644
--- a/tests/forms_tests/field_tests/test_filefield.py
+++ b/tests/forms_tests/field_tests/test_filefield.py
@@ -7,54 +7,74 @@ from django.test import SimpleTestCase
class FileFieldTest(SimpleTestCase):
-
def test_filefield_1(self):
f = FileField()
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('')
+ f.clean("")
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('', '')
- self.assertEqual('files/test1.pdf', f.clean('', 'files/test1.pdf'))
+ f.clean("", "")
+ self.assertEqual("files/test1.pdf", f.clean("", "files/test1.pdf"))
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(None)
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean(None, '')
- self.assertEqual('files/test2.pdf', f.clean(None, 'files/test2.pdf'))
+ f.clean(None, "")
+ self.assertEqual("files/test2.pdf", f.clean(None, "files/test2.pdf"))
no_file_msg = "'No file was submitted. Check the encoding type on the form.'"
- file = SimpleUploadedFile(None, b'')
- file._name = ''
+ file = SimpleUploadedFile(None, b"")
+ file._name = ""
with self.assertRaisesMessage(ValidationError, no_file_msg):
f.clean(file)
with self.assertRaisesMessage(ValidationError, no_file_msg):
- f.clean(file, '')
- self.assertEqual('files/test3.pdf', f.clean(None, 'files/test3.pdf'))
+ f.clean(file, "")
+ self.assertEqual("files/test3.pdf", f.clean(None, "files/test3.pdf"))
with self.assertRaisesMessage(ValidationError, no_file_msg):
- f.clean('some content that is not a file')
- with self.assertRaisesMessage(ValidationError, "'The submitted file is empty.'"):
- f.clean(SimpleUploadedFile('name', None))
- with self.assertRaisesMessage(ValidationError, "'The submitted file is empty.'"):
- f.clean(SimpleUploadedFile('name', b''))
- self.assertEqual(SimpleUploadedFile, type(f.clean(SimpleUploadedFile('name', b'Some File Content'))))
+ f.clean("some content that is not a file")
+ with self.assertRaisesMessage(
+ ValidationError, "'The submitted file is empty.'"
+ ):
+ f.clean(SimpleUploadedFile("name", None))
+ with self.assertRaisesMessage(
+ ValidationError, "'The submitted file is empty.'"
+ ):
+ f.clean(SimpleUploadedFile("name", b""))
+ self.assertEqual(
+ SimpleUploadedFile,
+ type(f.clean(SimpleUploadedFile("name", b"Some File Content"))),
+ )
self.assertIsInstance(
- f.clean(SimpleUploadedFile('我隻氣墊船裝滿晒鱔.txt', 'मेरी मँडराने वाली नाव सर्पमीनों से भरी ह'.encode())),
- SimpleUploadedFile
+ f.clean(
+ SimpleUploadedFile(
+ "我隻氣墊船裝滿晒鱔.txt", "मेरी मँडराने वाली नाव सर्पमीनों से भरी ह".encode()
+ )
+ ),
+ SimpleUploadedFile,
)
self.assertIsInstance(
- f.clean(SimpleUploadedFile('name', b'Some File Content'), 'files/test4.pdf'),
- SimpleUploadedFile
+ f.clean(
+ SimpleUploadedFile("name", b"Some File Content"), "files/test4.pdf"
+ ),
+ SimpleUploadedFile,
)
def test_filefield_2(self):
f = FileField(max_length=5)
- with self.assertRaisesMessage(ValidationError, "'Ensure this filename has at most 5 characters (it has 18).'"):
- f.clean(SimpleUploadedFile('test_maxlength.txt', b'hello world'))
- self.assertEqual('files/test1.pdf', f.clean('', 'files/test1.pdf'))
- self.assertEqual('files/test2.pdf', f.clean(None, 'files/test2.pdf'))
- self.assertIsInstance(f.clean(SimpleUploadedFile('name', b'Some File Content')), SimpleUploadedFile)
+ with self.assertRaisesMessage(
+ ValidationError,
+ "'Ensure this filename has at most 5 characters (it has 18).'",
+ ):
+ f.clean(SimpleUploadedFile("test_maxlength.txt", b"hello world"))
+ self.assertEqual("files/test1.pdf", f.clean("", "files/test1.pdf"))
+ self.assertEqual("files/test2.pdf", f.clean(None, "files/test2.pdf"))
+ self.assertIsInstance(
+ f.clean(SimpleUploadedFile("name", b"Some File Content")),
+ SimpleUploadedFile,
+ )
def test_filefield_3(self):
f = FileField(allow_empty_file=True)
- self.assertIsInstance(f.clean(SimpleUploadedFile('name', b'')), SimpleUploadedFile)
+ self.assertIsInstance(
+ f.clean(SimpleUploadedFile("name", b"")), SimpleUploadedFile
+ )
def test_filefield_changed(self):
"""
@@ -65,21 +85,27 @@ class FileFieldTest(SimpleTestCase):
f = FileField()
# No file was uploaded and no initial data.
- self.assertFalse(f.has_changed('', None))
+ self.assertFalse(f.has_changed("", None))
# A file was uploaded and no initial data.
- self.assertTrue(f.has_changed('', {'filename': 'resume.txt', 'content': 'My resume'}))
+ self.assertTrue(
+ f.has_changed("", {"filename": "resume.txt", "content": "My resume"})
+ )
# A file was not uploaded, but there is initial data
- self.assertFalse(f.has_changed('resume.txt', None))
+ self.assertFalse(f.has_changed("resume.txt", None))
# A file was uploaded and there is initial data (file identity is not dealt
# with here)
- self.assertTrue(f.has_changed('resume.txt', {'filename': 'resume.txt', 'content': 'My resume'}))
+ self.assertTrue(
+ f.has_changed(
+ "resume.txt", {"filename": "resume.txt", "content": "My resume"}
+ )
+ )
def test_disabled_has_changed(self):
f = FileField(disabled=True)
- self.assertIs(f.has_changed('x', 'y'), False)
+ self.assertIs(f.has_changed("x", "y"), False)
def test_file_picklable(self):
self.assertIsInstance(pickle.loads(pickle.dumps(FileField())), FileField)
diff --git a/tests/forms_tests/field_tests/test_filepathfield.py b/tests/forms_tests/field_tests/test_filepathfield.py
index bdd55c32a5..ca0f6f3a7a 100644
--- a/tests/forms_tests/field_tests/test_filepathfield.py
+++ b/tests/forms_tests/field_tests/test_filepathfield.py
@@ -10,8 +10,8 @@ PATH = os.path.dirname(os.path.abspath(__file__))
def fix_os_paths(x):
if isinstance(x, str):
if x.startswith(PATH):
- x = x[len(PATH):]
- return x.replace('\\', '/')
+ x = x[len(PATH) :]
+ return x.replace("\\", "/")
elif isinstance(x, tuple):
return tuple(fix_os_paths(list(x)))
elif isinstance(x, list):
@@ -22,34 +22,34 @@ def fix_os_paths(x):
class FilePathFieldTest(SimpleTestCase):
expected_choices = [
- ('/filepathfield_test_dir/__init__.py', '__init__.py'),
- ('/filepathfield_test_dir/a.py', 'a.py'),
- ('/filepathfield_test_dir/ab.py', 'ab.py'),
- ('/filepathfield_test_dir/b.py', 'b.py'),
- ('/filepathfield_test_dir/c/__init__.py', '__init__.py'),
- ('/filepathfield_test_dir/c/d.py', 'd.py'),
- ('/filepathfield_test_dir/c/e.py', 'e.py'),
- ('/filepathfield_test_dir/c/f/__init__.py', '__init__.py'),
- ('/filepathfield_test_dir/c/f/g.py', 'g.py'),
- ('/filepathfield_test_dir/h/__init__.py', '__init__.py'),
- ('/filepathfield_test_dir/j/__init__.py', '__init__.py'),
+ ("/filepathfield_test_dir/__init__.py", "__init__.py"),
+ ("/filepathfield_test_dir/a.py", "a.py"),
+ ("/filepathfield_test_dir/ab.py", "ab.py"),
+ ("/filepathfield_test_dir/b.py", "b.py"),
+ ("/filepathfield_test_dir/c/__init__.py", "__init__.py"),
+ ("/filepathfield_test_dir/c/d.py", "d.py"),
+ ("/filepathfield_test_dir/c/e.py", "e.py"),
+ ("/filepathfield_test_dir/c/f/__init__.py", "__init__.py"),
+ ("/filepathfield_test_dir/c/f/g.py", "g.py"),
+ ("/filepathfield_test_dir/h/__init__.py", "__init__.py"),
+ ("/filepathfield_test_dir/j/__init__.py", "__init__.py"),
]
- path = os.path.join(PATH, 'filepathfield_test_dir') + '/'
+ path = os.path.join(PATH, "filepathfield_test_dir") + "/"
def assertChoices(self, field, expected_choices):
self.assertEqual(fix_os_paths(field.choices), expected_choices)
def test_fix_os_paths(self):
- self.assertEqual(fix_os_paths(self.path), ('/filepathfield_test_dir/'))
+ self.assertEqual(fix_os_paths(self.path), ("/filepathfield_test_dir/"))
def test_nonexistent_path(self):
- with self.assertRaisesMessage(FileNotFoundError, 'nonexistent'):
- FilePathField(path='nonexistent')
+ with self.assertRaisesMessage(FileNotFoundError, "nonexistent"):
+ FilePathField(path="nonexistent")
def test_no_options(self):
f = FilePathField(path=self.path)
expected = [
- ('/filepathfield_test_dir/README', 'README'),
+ ("/filepathfield_test_dir/README", "README"),
] + self.expected_choices[:4]
self.assertChoices(f, expected)
@@ -57,48 +57,59 @@ class FilePathFieldTest(SimpleTestCase):
f = FilePathField(path=self.path)
msg = "'Select a valid choice. a.py is not one of the available choices.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('a.py')
- self.assertEqual(fix_os_paths(f.clean(self.path + 'a.py')), '/filepathfield_test_dir/a.py')
+ f.clean("a.py")
+ self.assertEqual(
+ fix_os_paths(f.clean(self.path + "a.py")), "/filepathfield_test_dir/a.py"
+ )
def test_match(self):
- f = FilePathField(path=self.path, match=r'^.*?\.py$')
+ f = FilePathField(path=self.path, match=r"^.*?\.py$")
self.assertChoices(f, self.expected_choices[:4])
def test_recursive(self):
- f = FilePathField(path=self.path, recursive=True, match=r'^.*?\.py$')
+ f = FilePathField(path=self.path, recursive=True, match=r"^.*?\.py$")
expected = [
- ('/filepathfield_test_dir/__init__.py', '__init__.py'),
- ('/filepathfield_test_dir/a.py', 'a.py'),
- ('/filepathfield_test_dir/ab.py', 'ab.py'),
- ('/filepathfield_test_dir/b.py', 'b.py'),
- ('/filepathfield_test_dir/c/__init__.py', 'c/__init__.py'),
- ('/filepathfield_test_dir/c/d.py', 'c/d.py'),
- ('/filepathfield_test_dir/c/e.py', 'c/e.py'),
- ('/filepathfield_test_dir/c/f/__init__.py', 'c/f/__init__.py'),
- ('/filepathfield_test_dir/c/f/g.py', 'c/f/g.py'),
- ('/filepathfield_test_dir/h/__init__.py', 'h/__init__.py'),
- ('/filepathfield_test_dir/j/__init__.py', 'j/__init__.py'),
-
+ ("/filepathfield_test_dir/__init__.py", "__init__.py"),
+ ("/filepathfield_test_dir/a.py", "a.py"),
+ ("/filepathfield_test_dir/ab.py", "ab.py"),
+ ("/filepathfield_test_dir/b.py", "b.py"),
+ ("/filepathfield_test_dir/c/__init__.py", "c/__init__.py"),
+ ("/filepathfield_test_dir/c/d.py", "c/d.py"),
+ ("/filepathfield_test_dir/c/e.py", "c/e.py"),
+ ("/filepathfield_test_dir/c/f/__init__.py", "c/f/__init__.py"),
+ ("/filepathfield_test_dir/c/f/g.py", "c/f/g.py"),
+ ("/filepathfield_test_dir/h/__init__.py", "h/__init__.py"),
+ ("/filepathfield_test_dir/j/__init__.py", "j/__init__.py"),
]
self.assertChoices(f, expected)
def test_allow_folders(self):
f = FilePathField(path=self.path, allow_folders=True, allow_files=False)
- self.assertChoices(f, [
- ('/filepathfield_test_dir/c', 'c'),
- ('/filepathfield_test_dir/h', 'h'),
- ('/filepathfield_test_dir/j', 'j'),
- ])
+ self.assertChoices(
+ f,
+ [
+ ("/filepathfield_test_dir/c", "c"),
+ ("/filepathfield_test_dir/h", "h"),
+ ("/filepathfield_test_dir/j", "j"),
+ ],
+ )
def test_recursive_no_folders_or_files(self):
- f = FilePathField(path=self.path, recursive=True, allow_folders=False, allow_files=False)
+ f = FilePathField(
+ path=self.path, recursive=True, allow_folders=False, allow_files=False
+ )
self.assertChoices(f, [])
def test_recursive_folders_without_files(self):
- f = FilePathField(path=self.path, recursive=True, allow_folders=True, allow_files=False)
- self.assertChoices(f, [
- ('/filepathfield_test_dir/c', 'c'),
- ('/filepathfield_test_dir/h', 'h'),
- ('/filepathfield_test_dir/j', 'j'),
- ('/filepathfield_test_dir/c/f', 'c/f'),
- ])
+ f = FilePathField(
+ path=self.path, recursive=True, allow_folders=True, allow_files=False
+ )
+ self.assertChoices(
+ f,
+ [
+ ("/filepathfield_test_dir/c", "c"),
+ ("/filepathfield_test_dir/h", "h"),
+ ("/filepathfield_test_dir/j", "j"),
+ ("/filepathfield_test_dir/c/f", "c/f"),
+ ],
+ )
diff --git a/tests/forms_tests/field_tests/test_floatfield.py b/tests/forms_tests/field_tests/test_floatfield.py
index 7330c33503..365684c2db 100644
--- a/tests/forms_tests/field_tests/test_floatfield.py
+++ b/tests/forms_tests/field_tests/test_floatfield.py
@@ -11,41 +11,42 @@ from . import FormFieldAssertionsMixin
class FloatFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
-
def test_floatfield_1(self):
f = FloatField()
- self.assertWidgetRendersTo(f, '<input step="any" type="number" name="f" id="id_f" required>')
+ self.assertWidgetRendersTo(
+ f, '<input step="any" type="number" name="f" id="id_f" required>'
+ )
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('')
+ f.clean("")
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(None)
- self.assertEqual(1.0, f.clean('1'))
- self.assertIsInstance(f.clean('1'), float)
- self.assertEqual(23.0, f.clean('23'))
- self.assertEqual(3.1400000000000001, f.clean('3.14'))
+ self.assertEqual(1.0, f.clean("1"))
+ self.assertIsInstance(f.clean("1"), float)
+ self.assertEqual(23.0, f.clean("23"))
+ self.assertEqual(3.1400000000000001, f.clean("3.14"))
self.assertEqual(3.1400000000000001, f.clean(3.14))
self.assertEqual(42.0, f.clean(42))
with self.assertRaisesMessage(ValidationError, "'Enter a number.'"):
- f.clean('a')
- self.assertEqual(1.0, f.clean('1.0 '))
- self.assertEqual(1.0, f.clean(' 1.0'))
- self.assertEqual(1.0, f.clean(' 1.0 '))
+ f.clean("a")
+ self.assertEqual(1.0, f.clean("1.0 "))
+ self.assertEqual(1.0, f.clean(" 1.0"))
+ self.assertEqual(1.0, f.clean(" 1.0 "))
with self.assertRaisesMessage(ValidationError, "'Enter a number.'"):
- f.clean('1.0a')
+ f.clean("1.0a")
self.assertIsNone(f.max_value)
self.assertIsNone(f.min_value)
with self.assertRaisesMessage(ValidationError, "'Enter a number.'"):
- f.clean('Infinity')
+ f.clean("Infinity")
with self.assertRaisesMessage(ValidationError, "'Enter a number.'"):
- f.clean('NaN')
+ f.clean("NaN")
with self.assertRaisesMessage(ValidationError, "'Enter a number.'"):
- f.clean('-Inf')
+ f.clean("-Inf")
def test_floatfield_2(self):
f = FloatField(required=False)
- self.assertIsNone(f.clean(''))
+ self.assertIsNone(f.clean(""))
self.assertIsNone(f.clean(None))
- self.assertEqual(1.0, f.clean('1'))
+ self.assertEqual(1.0, f.clean("1"))
self.assertIsNone(f.max_value)
self.assertIsNone(f.min_value)
@@ -55,17 +56,21 @@ class FloatFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
f,
'<input step="any" name="f" min="0.5" max="1.5" type="number" id="id_f" required>',
)
- with self.assertRaisesMessage(ValidationError, "'Ensure this value is less than or equal to 1.5.'"):
- f.clean('1.6')
- with self.assertRaisesMessage(ValidationError, "'Ensure this value is greater than or equal to 0.5.'"):
- f.clean('0.4')
- self.assertEqual(1.5, f.clean('1.5'))
- self.assertEqual(0.5, f.clean('0.5'))
+ with self.assertRaisesMessage(
+ ValidationError, "'Ensure this value is less than or equal to 1.5.'"
+ ):
+ f.clean("1.6")
+ with self.assertRaisesMessage(
+ ValidationError, "'Ensure this value is greater than or equal to 0.5.'"
+ ):
+ f.clean("0.4")
+ self.assertEqual(1.5, f.clean("1.5"))
+ self.assertEqual(0.5, f.clean("0.5"))
self.assertEqual(f.max_value, 1.5)
self.assertEqual(f.min_value, 0.5)
def test_floatfield_widget_attrs(self):
- f = FloatField(widget=NumberInput(attrs={'step': 0.01, 'max': 1.0, 'min': 0.0}))
+ f = FloatField(widget=NumberInput(attrs={"step": 0.01, "max": 1.0, "min": 0.0}))
self.assertWidgetRendersTo(
f,
'<input step="0.01" name="f" min="0.0" max="1.0" type="number" id="id_f" required>',
@@ -82,9 +87,9 @@ class FloatFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
def test_floatfield_changed(self):
f = FloatField()
n = 4.35
- self.assertFalse(f.has_changed(n, '4.3500'))
+ self.assertFalse(f.has_changed(n, "4.3500"))
- with translation.override('fr'):
+ with translation.override("fr"):
f = FloatField(localize=True)
localized_n = formats.localize_input(n) # -> '4,35' in French
self.assertFalse(f.has_changed(n, localized_n))
@@ -94,31 +99,35 @@ class FloatFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
# format-related settings will take precedence over locale-dictated
# formats.
@ignore_warnings(category=RemovedInDjango50Warning)
- @override_settings(USE_L10N=False, DECIMAL_SEPARATOR=',')
+ @override_settings(USE_L10N=False, DECIMAL_SEPARATOR=",")
def test_decimalfield_support_decimal_separator(self):
f = FloatField(localize=True)
- self.assertEqual(f.clean('1001,10'), 1001.10)
- self.assertEqual(f.clean('1001.10'), 1001.10)
+ self.assertEqual(f.clean("1001,10"), 1001.10)
+ self.assertEqual(f.clean("1001.10"), 1001.10)
# RemovedInDjango50Warning: When the deprecation ends, remove
# @ignore_warnings and USE_L10N=False. The test should remain because
# format-related settings will take precedence over locale-dictated
# formats.
@ignore_warnings(category=RemovedInDjango50Warning)
- @override_settings(USE_L10N=False, DECIMAL_SEPARATOR=',', USE_THOUSAND_SEPARATOR=True,
- THOUSAND_SEPARATOR='.')
+ @override_settings(
+ USE_L10N=False,
+ DECIMAL_SEPARATOR=",",
+ USE_THOUSAND_SEPARATOR=True,
+ THOUSAND_SEPARATOR=".",
+ )
def test_decimalfield_support_thousands_separator(self):
f = FloatField(localize=True)
- self.assertEqual(f.clean('1.001,10'), 1001.10)
+ self.assertEqual(f.clean("1.001,10"), 1001.10)
msg = "'Enter a number.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('1,001.1')
+ f.clean("1,001.1")
-@override_settings(ROOT_URLCONF='forms_tests.urls')
+@override_settings(ROOT_URLCONF="forms_tests.urls")
class FloatFieldHTMLTest(SeleniumTestCase):
- available_apps = ['forms_tests']
+ available_apps = ["forms_tests"]
def test_float_field_rendering_passes_client_side_validation(self):
"""
@@ -127,9 +136,9 @@ class FloatFieldHTMLTest(SeleniumTestCase):
"""
from selenium.webdriver.common.by import By
- self.selenium.get(self.live_server_url + reverse('form_view'))
- number_input = self.selenium.find_element(By.ID, 'id_number')
- number_input.send_keys('0.5')
+ self.selenium.get(self.live_server_url + reverse("form_view"))
+ number_input = self.selenium.find_element(By.ID, "id_number")
+ number_input.send_keys("0.5")
is_valid = self.selenium.execute_script(
"return document.getElementById('id_number').checkValidity()"
)
diff --git a/tests/forms_tests/field_tests/test_genericipaddressfield.py b/tests/forms_tests/field_tests/test_genericipaddressfield.py
index 92dbd71a28..80722f5c65 100644
--- a/tests/forms_tests/field_tests/test_genericipaddressfield.py
+++ b/tests/forms_tests/field_tests/test_genericipaddressfield.py
@@ -4,125 +4,186 @@ from django.test import SimpleTestCase
class GenericIPAddressFieldTest(SimpleTestCase):
-
def test_generic_ipaddress_invalid_arguments(self):
with self.assertRaises(ValueError):
- GenericIPAddressField(protocol='hamster')
+ GenericIPAddressField(protocol="hamster")
with self.assertRaises(ValueError):
- GenericIPAddressField(protocol='ipv4', unpack_ipv4=True)
+ GenericIPAddressField(protocol="ipv4", unpack_ipv4=True)
def test_generic_ipaddress_as_generic(self):
# The edge cases of the IPv6 validation code are not deeply tested
# here, they are covered in the tests for django.utils.ipv6
f = GenericIPAddressField()
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('')
+ f.clean("")
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(None)
- self.assertEqual(f.clean(' 127.0.0.1 '), '127.0.0.1')
- with self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 or IPv6 address.'"):
- f.clean('foo')
- with self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 or IPv6 address.'"):
- f.clean('127.0.0.')
- with self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 or IPv6 address.'"):
- f.clean('1.2.3.4.5')
- with self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 or IPv6 address.'"):
- f.clean('256.125.1.5')
- self.assertEqual(f.clean(' fe80::223:6cff:fe8a:2e8a '), 'fe80::223:6cff:fe8a:2e8a')
- self.assertEqual(f.clean(' 2a02::223:6cff:fe8a:2e8a '), '2a02::223:6cff:fe8a:2e8a')
- with self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'"):
- f.clean('12345:2:3:4')
- with self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'"):
- f.clean('1::2:3::4')
- with self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'"):
- f.clean('foo::223:6cff:fe8a:2e8a')
- with self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'"):
- f.clean('1::2:3:4:5:6:7:8')
- with self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'"):
- f.clean('1:2')
+ self.assertEqual(f.clean(" 127.0.0.1 "), "127.0.0.1")
+ with self.assertRaisesMessage(
+ ValidationError, "'Enter a valid IPv4 or IPv6 address.'"
+ ):
+ f.clean("foo")
+ with self.assertRaisesMessage(
+ ValidationError, "'Enter a valid IPv4 or IPv6 address.'"
+ ):
+ f.clean("127.0.0.")
+ with self.assertRaisesMessage(
+ ValidationError, "'Enter a valid IPv4 or IPv6 address.'"
+ ):
+ f.clean("1.2.3.4.5")
+ with self.assertRaisesMessage(
+ ValidationError, "'Enter a valid IPv4 or IPv6 address.'"
+ ):
+ f.clean("256.125.1.5")
+ self.assertEqual(
+ f.clean(" fe80::223:6cff:fe8a:2e8a "), "fe80::223:6cff:fe8a:2e8a"
+ )
+ self.assertEqual(
+ f.clean(" 2a02::223:6cff:fe8a:2e8a "), "2a02::223:6cff:fe8a:2e8a"
+ )
+ with self.assertRaisesMessage(
+ ValidationError, "'This is not a valid IPv6 address.'"
+ ):
+ f.clean("12345:2:3:4")
+ with self.assertRaisesMessage(
+ ValidationError, "'This is not a valid IPv6 address.'"
+ ):
+ f.clean("1::2:3::4")
+ with self.assertRaisesMessage(
+ ValidationError, "'This is not a valid IPv6 address.'"
+ ):
+ f.clean("foo::223:6cff:fe8a:2e8a")
+ with self.assertRaisesMessage(
+ ValidationError, "'This is not a valid IPv6 address.'"
+ ):
+ f.clean("1::2:3:4:5:6:7:8")
+ with self.assertRaisesMessage(
+ ValidationError, "'This is not a valid IPv6 address.'"
+ ):
+ f.clean("1:2")
def test_generic_ipaddress_as_ipv4_only(self):
f = GenericIPAddressField(protocol="IPv4")
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('')
+ f.clean("")
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(None)
- self.assertEqual(f.clean(' 127.0.0.1 '), '127.0.0.1')
+ self.assertEqual(f.clean(" 127.0.0.1 "), "127.0.0.1")
with self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 address.'"):
- f.clean('foo')
+ f.clean("foo")
with self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 address.'"):
- f.clean('127.0.0.')
+ f.clean("127.0.0.")
with self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 address.'"):
- f.clean('1.2.3.4.5')
+ f.clean("1.2.3.4.5")
with self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 address.'"):
- f.clean('256.125.1.5')
+ f.clean("256.125.1.5")
with self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 address.'"):
- f.clean('fe80::223:6cff:fe8a:2e8a')
+ f.clean("fe80::223:6cff:fe8a:2e8a")
with self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 address.'"):
- f.clean('2a02::223:6cff:fe8a:2e8a')
+ f.clean("2a02::223:6cff:fe8a:2e8a")
def test_generic_ipaddress_as_ipv6_only(self):
f = GenericIPAddressField(protocol="IPv6")
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('')
+ f.clean("")
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(None)
with self.assertRaisesMessage(ValidationError, "'Enter a valid IPv6 address.'"):
- f.clean('127.0.0.1')
+ f.clean("127.0.0.1")
with self.assertRaisesMessage(ValidationError, "'Enter a valid IPv6 address.'"):
- f.clean('foo')
+ f.clean("foo")
with self.assertRaisesMessage(ValidationError, "'Enter a valid IPv6 address.'"):
- f.clean('127.0.0.')
+ f.clean("127.0.0.")
with self.assertRaisesMessage(ValidationError, "'Enter a valid IPv6 address.'"):
- f.clean('1.2.3.4.5')
+ f.clean("1.2.3.4.5")
with self.assertRaisesMessage(ValidationError, "'Enter a valid IPv6 address.'"):
- f.clean('256.125.1.5')
- self.assertEqual(f.clean(' fe80::223:6cff:fe8a:2e8a '), 'fe80::223:6cff:fe8a:2e8a')
- self.assertEqual(f.clean(' 2a02::223:6cff:fe8a:2e8a '), '2a02::223:6cff:fe8a:2e8a')
- with self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'"):
- f.clean('12345:2:3:4')
- with self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'"):
- f.clean('1::2:3::4')
- with self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'"):
- f.clean('foo::223:6cff:fe8a:2e8a')
- with self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'"):
- f.clean('1::2:3:4:5:6:7:8')
- with self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'"):
- f.clean('1:2')
+ f.clean("256.125.1.5")
+ self.assertEqual(
+ f.clean(" fe80::223:6cff:fe8a:2e8a "), "fe80::223:6cff:fe8a:2e8a"
+ )
+ self.assertEqual(
+ f.clean(" 2a02::223:6cff:fe8a:2e8a "), "2a02::223:6cff:fe8a:2e8a"
+ )
+ with self.assertRaisesMessage(
+ ValidationError, "'This is not a valid IPv6 address.'"
+ ):
+ f.clean("12345:2:3:4")
+ with self.assertRaisesMessage(
+ ValidationError, "'This is not a valid IPv6 address.'"
+ ):
+ f.clean("1::2:3::4")
+ with self.assertRaisesMessage(
+ ValidationError, "'This is not a valid IPv6 address.'"
+ ):
+ f.clean("foo::223:6cff:fe8a:2e8a")
+ with self.assertRaisesMessage(
+ ValidationError, "'This is not a valid IPv6 address.'"
+ ):
+ f.clean("1::2:3:4:5:6:7:8")
+ with self.assertRaisesMessage(
+ ValidationError, "'This is not a valid IPv6 address.'"
+ ):
+ f.clean("1:2")
def test_generic_ipaddress_as_generic_not_required(self):
f = GenericIPAddressField(required=False)
- self.assertEqual(f.clean(''), '')
- self.assertEqual(f.clean(None), '')
- self.assertEqual(f.clean('127.0.0.1'), '127.0.0.1')
- with self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 or IPv6 address.'"):
- f.clean('foo')
- with self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 or IPv6 address.'"):
- f.clean('127.0.0.')
- with self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 or IPv6 address.'"):
- f.clean('1.2.3.4.5')
- with self.assertRaisesMessage(ValidationError, "'Enter a valid IPv4 or IPv6 address.'"):
- f.clean('256.125.1.5')
- self.assertEqual(f.clean(' fe80::223:6cff:fe8a:2e8a '), 'fe80::223:6cff:fe8a:2e8a')
- self.assertEqual(f.clean(' 2a02::223:6cff:fe8a:2e8a '), '2a02::223:6cff:fe8a:2e8a')
- with self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'"):
- f.clean('12345:2:3:4')
- with self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'"):
- f.clean('1::2:3::4')
- with self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'"):
- f.clean('foo::223:6cff:fe8a:2e8a')
- with self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'"):
- f.clean('1::2:3:4:5:6:7:8')
- with self.assertRaisesMessage(ValidationError, "'This is not a valid IPv6 address.'"):
- f.clean('1:2')
+ self.assertEqual(f.clean(""), "")
+ self.assertEqual(f.clean(None), "")
+ self.assertEqual(f.clean("127.0.0.1"), "127.0.0.1")
+ with self.assertRaisesMessage(
+ ValidationError, "'Enter a valid IPv4 or IPv6 address.'"
+ ):
+ f.clean("foo")
+ with self.assertRaisesMessage(
+ ValidationError, "'Enter a valid IPv4 or IPv6 address.'"
+ ):
+ f.clean("127.0.0.")
+ with self.assertRaisesMessage(
+ ValidationError, "'Enter a valid IPv4 or IPv6 address.'"
+ ):
+ f.clean("1.2.3.4.5")
+ with self.assertRaisesMessage(
+ ValidationError, "'Enter a valid IPv4 or IPv6 address.'"
+ ):
+ f.clean("256.125.1.5")
+ self.assertEqual(
+ f.clean(" fe80::223:6cff:fe8a:2e8a "), "fe80::223:6cff:fe8a:2e8a"
+ )
+ self.assertEqual(
+ f.clean(" 2a02::223:6cff:fe8a:2e8a "), "2a02::223:6cff:fe8a:2e8a"
+ )
+ with self.assertRaisesMessage(
+ ValidationError, "'This is not a valid IPv6 address.'"
+ ):
+ f.clean("12345:2:3:4")
+ with self.assertRaisesMessage(
+ ValidationError, "'This is not a valid IPv6 address.'"
+ ):
+ f.clean("1::2:3::4")
+ with self.assertRaisesMessage(
+ ValidationError, "'This is not a valid IPv6 address.'"
+ ):
+ f.clean("foo::223:6cff:fe8a:2e8a")
+ with self.assertRaisesMessage(
+ ValidationError, "'This is not a valid IPv6 address.'"
+ ):
+ f.clean("1::2:3:4:5:6:7:8")
+ with self.assertRaisesMessage(
+ ValidationError, "'This is not a valid IPv6 address.'"
+ ):
+ f.clean("1:2")
def test_generic_ipaddress_normalization(self):
# Test the normalizing code
f = GenericIPAddressField()
- self.assertEqual(f.clean(' ::ffff:0a0a:0a0a '), '::ffff:10.10.10.10')
- self.assertEqual(f.clean(' ::ffff:10.10.10.10 '), '::ffff:10.10.10.10')
- self.assertEqual(f.clean(' 2001:000:a:0000:0:fe:fe:beef '), '2001:0:a::fe:fe:beef')
- self.assertEqual(f.clean(' 2001::a:0000:0:fe:fe:beef '), '2001:0:a::fe:fe:beef')
+ self.assertEqual(f.clean(" ::ffff:0a0a:0a0a "), "::ffff:10.10.10.10")
+ self.assertEqual(f.clean(" ::ffff:10.10.10.10 "), "::ffff:10.10.10.10")
+ self.assertEqual(
+ f.clean(" 2001:000:a:0000:0:fe:fe:beef "), "2001:0:a::fe:fe:beef"
+ )
+ self.assertEqual(
+ f.clean(" 2001::a:0000:0:fe:fe:beef "), "2001:0:a::fe:fe:beef"
+ )
f = GenericIPAddressField(unpack_ipv4=True)
- self.assertEqual(f.clean(' ::ffff:0a0a:0a0a'), '10.10.10.10')
+ self.assertEqual(f.clean(" ::ffff:0a0a:0a0a"), "10.10.10.10")
diff --git a/tests/forms_tests/field_tests/test_imagefield.py b/tests/forms_tests/field_tests/test_imagefield.py
index 1cb34bf058..c138ee5c09 100644
--- a/tests/forms_tests/field_tests/test_imagefield.py
+++ b/tests/forms_tests/field_tests/test_imagefield.py
@@ -2,9 +2,7 @@ import os
import unittest
from django.core.exceptions import ValidationError
-from django.core.files.uploadedfile import (
- SimpleUploadedFile, TemporaryUploadedFile,
-)
+from django.core.files.uploadedfile import SimpleUploadedFile, TemporaryUploadedFile
from django.forms import ClearableFileInput, FileInput, ImageField, Widget
from django.test import SimpleTestCase
@@ -17,26 +15,27 @@ except ImportError:
def get_img_path(path):
- return os.path.join(os.path.abspath(os.path.join(__file__, '..', '..')), 'tests', path)
+ return os.path.join(
+ os.path.abspath(os.path.join(__file__, "..", "..")), "tests", path
+ )
@unittest.skipUnless(Image, "Pillow is required to test ImageField")
class ImageFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
-
def test_imagefield_annotate_with_image_after_clean(self):
f = ImageField()
- img_path = get_img_path('filepath_test_files/1x1.png')
- with open(img_path, 'rb') as img_file:
+ img_path = get_img_path("filepath_test_files/1x1.png")
+ with open(img_path, "rb") as img_file:
img_data = img_file.read()
- img_file = SimpleUploadedFile('1x1.png', img_data)
- img_file.content_type = 'text/plain'
+ img_file = SimpleUploadedFile("1x1.png", img_data)
+ img_file.content_type = "text/plain"
uploaded_file = f.clean(img_file)
- self.assertEqual('PNG', uploaded_file.image.format)
- self.assertEqual('image/png', uploaded_file.content_type)
+ self.assertEqual("PNG", uploaded_file.image.format)
+ self.assertEqual("image/png", uploaded_file.content_type)
def test_imagefield_annotate_with_bitmap_image_after_clean(self):
"""
@@ -44,42 +43,47 @@ class ImageFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
of the image (#24948).
"""
from PIL.BmpImagePlugin import BmpImageFile
+
try:
Image.register_mime(BmpImageFile.format, None)
f = ImageField()
- img_path = get_img_path('filepath_test_files/1x1.bmp')
- with open(img_path, 'rb') as img_file:
+ img_path = get_img_path("filepath_test_files/1x1.bmp")
+ with open(img_path, "rb") as img_file:
img_data = img_file.read()
- img_file = SimpleUploadedFile('1x1.bmp', img_data)
- img_file.content_type = 'text/plain'
+ img_file = SimpleUploadedFile("1x1.bmp", img_data)
+ img_file.content_type = "text/plain"
uploaded_file = f.clean(img_file)
- self.assertEqual('BMP', uploaded_file.image.format)
+ self.assertEqual("BMP", uploaded_file.image.format)
self.assertIsNone(uploaded_file.content_type)
finally:
- Image.register_mime(BmpImageFile.format, 'image/bmp')
+ Image.register_mime(BmpImageFile.format, "image/bmp")
def test_file_extension_validation(self):
f = ImageField()
- img_path = get_img_path('filepath_test_files/1x1.png')
- with open(img_path, 'rb') as img_file:
+ img_path = get_img_path("filepath_test_files/1x1.png")
+ with open(img_path, "rb") as img_file:
img_data = img_file.read()
- img_file = SimpleUploadedFile('1x1.txt', img_data)
- with self.assertRaisesMessage(ValidationError, 'File extension “txt” is not allowed.'):
+ img_file = SimpleUploadedFile("1x1.txt", img_data)
+ with self.assertRaisesMessage(
+ ValidationError, "File extension “txt” is not allowed."
+ ):
f.clean(img_file)
def test_corrupted_image(self):
f = ImageField()
- img_file = SimpleUploadedFile('not_an_image.jpg', b'not an image')
+ img_file = SimpleUploadedFile("not_an_image.jpg", b"not an image")
msg = (
- 'Upload a valid image. The file you uploaded was either not an '
- 'image or a corrupted image.'
+ "Upload a valid image. The file you uploaded was either not an "
+ "image or a corrupted image."
)
with self.assertRaisesMessage(ValidationError, msg):
f.clean(img_file)
- with TemporaryUploadedFile('not_an_image_tmp.png', 'text/plain', 1, 'utf-8') as tmp_file:
+ with TemporaryUploadedFile(
+ "not_an_image_tmp.png", "text/plain", 1, "utf-8"
+ ) as tmp_file:
with self.assertRaisesMessage(ValidationError, msg):
f.clean(tmp_file)
@@ -87,16 +91,22 @@ class ImageFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
f = ImageField()
# Nothing added for non-FileInput widgets.
self.assertEqual(f.widget_attrs(Widget()), {})
- self.assertEqual(f.widget_attrs(FileInput()), {'accept': 'image/*'})
- self.assertEqual(f.widget_attrs(ClearableFileInput()), {'accept': 'image/*'})
- self.assertWidgetRendersTo(f, '<input type="file" name="f" accept="image/*" required id="id_f" />')
+ self.assertEqual(f.widget_attrs(FileInput()), {"accept": "image/*"})
+ self.assertEqual(f.widget_attrs(ClearableFileInput()), {"accept": "image/*"})
+ self.assertWidgetRendersTo(
+ f, '<input type="file" name="f" accept="image/*" required id="id_f" />'
+ )
def test_widget_attrs_accept_specified(self):
- f = ImageField(widget=FileInput(attrs={'accept': 'image/png'}))
+ f = ImageField(widget=FileInput(attrs={"accept": "image/png"}))
self.assertEqual(f.widget_attrs(f.widget), {})
- self.assertWidgetRendersTo(f, '<input type="file" name="f" accept="image/png" required id="id_f" />')
+ self.assertWidgetRendersTo(
+ f, '<input type="file" name="f" accept="image/png" required id="id_f" />'
+ )
def test_widget_attrs_accept_false(self):
- f = ImageField(widget=FileInput(attrs={'accept': False}))
+ f = ImageField(widget=FileInput(attrs={"accept": False}))
self.assertEqual(f.widget_attrs(f.widget), {})
- self.assertWidgetRendersTo(f, '<input type="file" name="f" required id="id_f" />')
+ self.assertWidgetRendersTo(
+ f, '<input type="file" name="f" required id="id_f" />'
+ )
diff --git a/tests/forms_tests/field_tests/test_integerfield.py b/tests/forms_tests/field_tests/test_integerfield.py
index 0dde7ff488..15314d53a4 100644
--- a/tests/forms_tests/field_tests/test_integerfield.py
+++ b/tests/forms_tests/field_tests/test_integerfield.py
@@ -6,91 +6,108 @@ from . import FormFieldAssertionsMixin
class IntegerFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
-
def test_integerfield_1(self):
f = IntegerField()
- self.assertWidgetRendersTo(f, '<input type="number" name="f" id="id_f" required>')
+ self.assertWidgetRendersTo(
+ f, '<input type="number" name="f" id="id_f" required>'
+ )
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('')
+ f.clean("")
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(None)
- self.assertEqual(1, f.clean('1'))
- self.assertIsInstance(f.clean('1'), int)
- self.assertEqual(23, f.clean('23'))
+ self.assertEqual(1, f.clean("1"))
+ self.assertIsInstance(f.clean("1"), int)
+ self.assertEqual(23, f.clean("23"))
with self.assertRaisesMessage(ValidationError, "'Enter a whole number.'"):
- f.clean('a')
+ f.clean("a")
self.assertEqual(42, f.clean(42))
with self.assertRaisesMessage(ValidationError, "'Enter a whole number.'"):
f.clean(3.14)
- self.assertEqual(1, f.clean('1 '))
- self.assertEqual(1, f.clean(' 1'))
- self.assertEqual(1, f.clean(' 1 '))
+ self.assertEqual(1, f.clean("1 "))
+ self.assertEqual(1, f.clean(" 1"))
+ self.assertEqual(1, f.clean(" 1 "))
with self.assertRaisesMessage(ValidationError, "'Enter a whole number.'"):
- f.clean('1a')
+ f.clean("1a")
self.assertIsNone(f.max_value)
self.assertIsNone(f.min_value)
def test_integerfield_2(self):
f = IntegerField(required=False)
- self.assertIsNone(f.clean(''))
- self.assertEqual('None', repr(f.clean('')))
+ self.assertIsNone(f.clean(""))
+ self.assertEqual("None", repr(f.clean("")))
self.assertIsNone(f.clean(None))
- self.assertEqual('None', repr(f.clean(None)))
- self.assertEqual(1, f.clean('1'))
- self.assertIsInstance(f.clean('1'), int)
- self.assertEqual(23, f.clean('23'))
+ self.assertEqual("None", repr(f.clean(None)))
+ self.assertEqual(1, f.clean("1"))
+ self.assertIsInstance(f.clean("1"), int)
+ self.assertEqual(23, f.clean("23"))
with self.assertRaisesMessage(ValidationError, "'Enter a whole number.'"):
- f.clean('a')
- self.assertEqual(1, f.clean('1 '))
- self.assertEqual(1, f.clean(' 1'))
- self.assertEqual(1, f.clean(' 1 '))
+ f.clean("a")
+ self.assertEqual(1, f.clean("1 "))
+ self.assertEqual(1, f.clean(" 1"))
+ self.assertEqual(1, f.clean(" 1 "))
with self.assertRaisesMessage(ValidationError, "'Enter a whole number.'"):
- f.clean('1a')
+ f.clean("1a")
self.assertIsNone(f.max_value)
self.assertIsNone(f.min_value)
def test_integerfield_3(self):
f = IntegerField(max_value=10)
- self.assertWidgetRendersTo(f, '<input max="10" type="number" name="f" id="id_f" required>')
+ self.assertWidgetRendersTo(
+ f, '<input max="10" type="number" name="f" id="id_f" required>'
+ )
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(None)
self.assertEqual(1, f.clean(1))
self.assertEqual(10, f.clean(10))
- with self.assertRaisesMessage(ValidationError, "'Ensure this value is less than or equal to 10.'"):
+ with self.assertRaisesMessage(
+ ValidationError, "'Ensure this value is less than or equal to 10.'"
+ ):
f.clean(11)
- self.assertEqual(10, f.clean('10'))
- with self.assertRaisesMessage(ValidationError, "'Ensure this value is less than or equal to 10.'"):
- f.clean('11')
+ self.assertEqual(10, f.clean("10"))
+ with self.assertRaisesMessage(
+ ValidationError, "'Ensure this value is less than or equal to 10.'"
+ ):
+ f.clean("11")
self.assertEqual(f.max_value, 10)
self.assertIsNone(f.min_value)
def test_integerfield_4(self):
f = IntegerField(min_value=10)
- self.assertWidgetRendersTo(f, '<input id="id_f" type="number" name="f" min="10" required>')
+ self.assertWidgetRendersTo(
+ f, '<input id="id_f" type="number" name="f" min="10" required>'
+ )
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(None)
- with self.assertRaisesMessage(ValidationError, "'Ensure this value is greater than or equal to 10.'"):
+ with self.assertRaisesMessage(
+ ValidationError, "'Ensure this value is greater than or equal to 10.'"
+ ):
f.clean(1)
self.assertEqual(10, f.clean(10))
self.assertEqual(11, f.clean(11))
- self.assertEqual(10, f.clean('10'))
- self.assertEqual(11, f.clean('11'))
+ self.assertEqual(10, f.clean("10"))
+ self.assertEqual(11, f.clean("11"))
self.assertIsNone(f.max_value)
self.assertEqual(f.min_value, 10)
def test_integerfield_5(self):
f = IntegerField(min_value=10, max_value=20)
- self.assertWidgetRendersTo(f, '<input id="id_f" max="20" type="number" name="f" min="10" required>')
+ self.assertWidgetRendersTo(
+ f, '<input id="id_f" max="20" type="number" name="f" min="10" required>'
+ )
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(None)
- with self.assertRaisesMessage(ValidationError, "'Ensure this value is greater than or equal to 10.'"):
+ with self.assertRaisesMessage(
+ ValidationError, "'Ensure this value is greater than or equal to 10.'"
+ ):
f.clean(1)
self.assertEqual(10, f.clean(10))
self.assertEqual(11, f.clean(11))
- self.assertEqual(10, f.clean('10'))
- self.assertEqual(11, f.clean('11'))
+ self.assertEqual(10, f.clean("10"))
+ self.assertEqual(11, f.clean("11"))
self.assertEqual(20, f.clean(20))
- with self.assertRaisesMessage(ValidationError, "'Ensure this value is less than or equal to 20.'"):
+ with self.assertRaisesMessage(
+ ValidationError, "'Ensure this value is less than or equal to 20.'"
+ ):
f.clean(21)
self.assertEqual(f.max_value, 20)
self.assertEqual(f.min_value, 10)
@@ -101,34 +118,37 @@ class IntegerFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
number input specific attributes.
"""
f1 = IntegerField(localize=True)
- self.assertWidgetRendersTo(f1, '<input id="id_f" name="f" type="text" required>')
+ self.assertWidgetRendersTo(
+ f1, '<input id="id_f" name="f" type="text" required>'
+ )
def test_integerfield_float(self):
f = IntegerField()
self.assertEqual(1, f.clean(1.0))
- self.assertEqual(1, f.clean('1.0'))
- self.assertEqual(1, f.clean(' 1.0 '))
- self.assertEqual(1, f.clean('1.'))
- self.assertEqual(1, f.clean(' 1. '))
+ self.assertEqual(1, f.clean("1.0"))
+ self.assertEqual(1, f.clean(" 1.0 "))
+ self.assertEqual(1, f.clean("1."))
+ self.assertEqual(1, f.clean(" 1. "))
with self.assertRaisesMessage(ValidationError, "'Enter a whole number.'"):
- f.clean('1.5')
+ f.clean("1.5")
with self.assertRaisesMessage(ValidationError, "'Enter a whole number.'"):
- f.clean('…')
+ f.clean("…")
def test_integerfield_big_num(self):
f = IntegerField()
self.assertEqual(9223372036854775808, f.clean(9223372036854775808))
- self.assertEqual(9223372036854775808, f.clean('9223372036854775808'))
- self.assertEqual(9223372036854775808, f.clean('9223372036854775808.0'))
+ self.assertEqual(9223372036854775808, f.clean("9223372036854775808"))
+ self.assertEqual(9223372036854775808, f.clean("9223372036854775808.0"))
def test_integerfield_unicode_number(self):
f = IntegerField()
- self.assertEqual(50, f.clean('50'))
+ self.assertEqual(50, f.clean("50"))
def test_integerfield_subclass(self):
"""
Class-defined widget is not overwritten by __init__() (#22245).
"""
+
class MyIntegerField(IntegerField):
widget = Textarea
diff --git a/tests/forms_tests/field_tests/test_jsonfield.py b/tests/forms_tests/field_tests/test_jsonfield.py
index b4f3e74f6a..be2b077e64 100644
--- a/tests/forms_tests/field_tests/test_jsonfield.py
+++ b/tests/forms_tests/field_tests/test_jsonfield.py
@@ -3,7 +3,12 @@ import uuid
from django.core.serializers.json import DjangoJSONEncoder
from django.forms import (
- CharField, Form, JSONField, Textarea, TextInput, ValidationError,
+ CharField,
+ Form,
+ JSONField,
+ Textarea,
+ TextInput,
+ ValidationError,
)
from django.test import SimpleTestCase
@@ -12,25 +17,25 @@ class JSONFieldTest(SimpleTestCase):
def test_valid(self):
field = JSONField()
value = field.clean('{"a": "b"}')
- self.assertEqual(value, {'a': 'b'})
+ self.assertEqual(value, {"a": "b"})
def test_valid_empty(self):
field = JSONField(required=False)
- self.assertIsNone(field.clean(''))
+ self.assertIsNone(field.clean(""))
self.assertIsNone(field.clean(None))
def test_invalid(self):
field = JSONField()
- with self.assertRaisesMessage(ValidationError, 'Enter a valid JSON.'):
- field.clean('{some badly formed: json}')
+ with self.assertRaisesMessage(ValidationError, "Enter a valid JSON."):
+ field.clean("{some badly formed: json}")
def test_prepare_value(self):
field = JSONField()
- self.assertEqual(field.prepare_value({'a': 'b'}), '{"a": "b"}')
- self.assertEqual(field.prepare_value(None), 'null')
- self.assertEqual(field.prepare_value('foo'), '"foo"')
- self.assertEqual(field.prepare_value('你好,世界'), '"你好,世界"')
- self.assertEqual(field.prepare_value({'a': '😀🐱'}), '{"a": "😀🐱"}')
+ self.assertEqual(field.prepare_value({"a": "b"}), '{"a": "b"}')
+ self.assertEqual(field.prepare_value(None), "null")
+ self.assertEqual(field.prepare_value("foo"), '"foo"')
+ self.assertEqual(field.prepare_value("你好,世界"), '"你好,世界"')
+ self.assertEqual(field.prepare_value({"a": "😀🐱"}), '{"a": "😀🐱"}')
self.assertEqual(
field.prepare_value(["你好,世界", "jaźń"]),
'["你好,世界", "jaźń"]',
@@ -46,6 +51,7 @@ class JSONFieldTest(SimpleTestCase):
def test_custom_widget_attribute(self):
"""The widget can be overridden with an attribute."""
+
class CustomJSONField(JSONField):
widget = TextInput
@@ -57,12 +63,12 @@ class JSONFieldTest(SimpleTestCase):
tests = [
'["a", "b", "c"]',
'{"a": 1, "b": 2}',
- '1',
- '1.5',
+ "1",
+ "1.5",
'"foo"',
- 'true',
- 'false',
- 'null',
+ "true",
+ "false",
+ "null",
]
for json_string in tests:
with self.subTest(json_string=json_string):
@@ -71,8 +77,8 @@ class JSONFieldTest(SimpleTestCase):
def test_has_changed(self):
field = JSONField()
- self.assertIs(field.has_changed({'a': True}, '{"a": 1}'), True)
- self.assertIs(field.has_changed({'a': 1, 'b': 2}, '{"b": 2, "a": 1}'), False)
+ self.assertIs(field.has_changed({"a": True}, '{"a": 1}'), True)
+ self.assertIs(field.has_changed({"a": 1, "b": 2}, '{"b": 2, "a": 1}'), False)
def test_custom_encoder_decoder(self):
class CustomDecoder(json.JSONDecoder):
@@ -80,11 +86,11 @@ class JSONFieldTest(SimpleTestCase):
return super().__init__(object_hook=self.as_uuid, *args, **kwargs)
def as_uuid(self, dct):
- if 'uuid' in dct:
- dct['uuid'] = uuid.UUID(dct['uuid'])
+ if "uuid" in dct:
+ dct["uuid"] = uuid.UUID(dct["uuid"])
return dct
- value = {'uuid': uuid.UUID('{c141e152-6550-4172-a784-05448d98204b}')}
+ value = {"uuid": uuid.UUID("{c141e152-6550-4172-a784-05448d98204b}")}
encoded_value = '{"uuid": "c141e152-6550-4172-a784-05448d98204b"}'
field = JSONField(encoder=DjangoJSONEncoder, decoder=CustomDecoder)
self.assertEqual(field.prepare_value(value), encoded_value)
@@ -94,8 +100,8 @@ class JSONFieldTest(SimpleTestCase):
class JSONForm(Form):
json_field = JSONField(disabled=True)
- form = JSONForm({'json_field': '["bar"]'}, initial={'json_field': ['foo']})
- self.assertIn('[&quot;foo&quot;]</textarea>', form.as_p())
+ form = JSONForm({"json_field": '["bar"]'}, initial={"json_field": ["foo"]})
+ self.assertIn("[&quot;foo&quot;]</textarea>", form.as_p())
def test_redisplay_none_input(self):
class JSONForm(Form):
@@ -103,29 +109,30 @@ class JSONFieldTest(SimpleTestCase):
tests = [
{},
- {'json_field': None},
+ {"json_field": None},
]
for data in tests:
with self.subTest(data=data):
form = JSONForm(data)
- self.assertEqual(form['json_field'].value(), 'null')
- self.assertIn('null</textarea>', form.as_p())
- self.assertEqual(form.errors['json_field'], ['This field is required.'])
+ self.assertEqual(form["json_field"].value(), "null")
+ self.assertIn("null</textarea>", form.as_p())
+ self.assertEqual(form.errors["json_field"], ["This field is required."])
def test_redisplay_wrong_input(self):
"""
Displaying a bound form (typically due to invalid input). The form
should not overquote JSONField inputs.
"""
+
class JSONForm(Form):
name = CharField(max_length=2)
json_field = JSONField()
# JSONField input is valid, name is too long.
- form = JSONForm({'name': 'xyz', 'json_field': '["foo"]'})
- self.assertNotIn('json_field', form.errors)
- self.assertIn('[&quot;foo&quot;]</textarea>', form.as_p())
+ form = JSONForm({"name": "xyz", "json_field": '["foo"]'})
+ self.assertNotIn("json_field", form.errors)
+ self.assertIn("[&quot;foo&quot;]</textarea>", form.as_p())
# Invalid JSONField.
- form = JSONForm({'name': 'xy', 'json_field': '{"foo"}'})
- self.assertEqual(form.errors['json_field'], ['Enter a valid JSON.'])
- self.assertIn('{&quot;foo&quot;}</textarea>', form.as_p())
+ form = JSONForm({"name": "xy", "json_field": '{"foo"}'})
+ self.assertEqual(form.errors["json_field"], ["Enter a valid JSON."])
+ self.assertIn("{&quot;foo&quot;}</textarea>", form.as_p())
diff --git a/tests/forms_tests/field_tests/test_multiplechoicefield.py b/tests/forms_tests/field_tests/test_multiplechoicefield.py
index 6dbeee2685..f316e1de8e 100644
--- a/tests/forms_tests/field_tests/test_multiplechoicefield.py
+++ b/tests/forms_tests/field_tests/test_multiplechoicefield.py
@@ -4,72 +4,75 @@ from django.test import SimpleTestCase
class MultipleChoiceFieldTest(SimpleTestCase):
-
def test_multiplechoicefield_1(self):
- f = MultipleChoiceField(choices=[('1', 'One'), ('2', 'Two')])
+ f = MultipleChoiceField(choices=[("1", "One"), ("2", "Two")])
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('')
+ f.clean("")
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(None)
- self.assertEqual(['1'], f.clean([1]))
- self.assertEqual(['1'], f.clean(['1']))
- self.assertEqual(['1', '2'], f.clean(['1', '2']))
- self.assertEqual(['1', '2'], f.clean([1, '2']))
- self.assertEqual(['1', '2'], f.clean((1, '2')))
+ self.assertEqual(["1"], f.clean([1]))
+ self.assertEqual(["1"], f.clean(["1"]))
+ self.assertEqual(["1", "2"], f.clean(["1", "2"]))
+ self.assertEqual(["1", "2"], f.clean([1, "2"]))
+ self.assertEqual(["1", "2"], f.clean((1, "2")))
with self.assertRaisesMessage(ValidationError, "'Enter a list of values.'"):
- f.clean('hello')
+ f.clean("hello")
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean([])
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(())
msg = "'Select a valid choice. 3 is not one of the available choices.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean(['3'])
+ f.clean(["3"])
def test_multiplechoicefield_2(self):
- f = MultipleChoiceField(choices=[('1', 'One'), ('2', 'Two')], required=False)
- self.assertEqual([], f.clean(''))
+ f = MultipleChoiceField(choices=[("1", "One"), ("2", "Two")], required=False)
+ self.assertEqual([], f.clean(""))
self.assertEqual([], f.clean(None))
- self.assertEqual(['1'], f.clean([1]))
- self.assertEqual(['1'], f.clean(['1']))
- self.assertEqual(['1', '2'], f.clean(['1', '2']))
- self.assertEqual(['1', '2'], f.clean([1, '2']))
- self.assertEqual(['1', '2'], f.clean((1, '2')))
+ self.assertEqual(["1"], f.clean([1]))
+ self.assertEqual(["1"], f.clean(["1"]))
+ self.assertEqual(["1", "2"], f.clean(["1", "2"]))
+ self.assertEqual(["1", "2"], f.clean([1, "2"]))
+ self.assertEqual(["1", "2"], f.clean((1, "2")))
with self.assertRaisesMessage(ValidationError, "'Enter a list of values.'"):
- f.clean('hello')
+ f.clean("hello")
self.assertEqual([], f.clean([]))
self.assertEqual([], f.clean(()))
msg = "'Select a valid choice. 3 is not one of the available choices.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean(['3'])
+ f.clean(["3"])
def test_multiplechoicefield_3(self):
f = MultipleChoiceField(
- choices=[('Numbers', (('1', 'One'), ('2', 'Two'))), ('Letters', (('3', 'A'), ('4', 'B'))), ('5', 'Other')]
+ choices=[
+ ("Numbers", (("1", "One"), ("2", "Two"))),
+ ("Letters", (("3", "A"), ("4", "B"))),
+ ("5", "Other"),
+ ]
)
- self.assertEqual(['1'], f.clean([1]))
- self.assertEqual(['1'], f.clean(['1']))
- self.assertEqual(['1', '5'], f.clean([1, 5]))
- self.assertEqual(['1', '5'], f.clean([1, '5']))
- self.assertEqual(['1', '5'], f.clean(['1', 5]))
- self.assertEqual(['1', '5'], f.clean(['1', '5']))
+ self.assertEqual(["1"], f.clean([1]))
+ self.assertEqual(["1"], f.clean(["1"]))
+ self.assertEqual(["1", "5"], f.clean([1, 5]))
+ self.assertEqual(["1", "5"], f.clean([1, "5"]))
+ self.assertEqual(["1", "5"], f.clean(["1", 5]))
+ self.assertEqual(["1", "5"], f.clean(["1", "5"]))
msg = "'Select a valid choice. 6 is not one of the available choices.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean(['6'])
+ f.clean(["6"])
msg = "'Select a valid choice. 6 is not one of the available choices.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean(['1', '6'])
+ f.clean(["1", "6"])
def test_multiplechoicefield_changed(self):
- f = MultipleChoiceField(choices=[('1', 'One'), ('2', 'Two'), ('3', 'Three')])
+ f = MultipleChoiceField(choices=[("1", "One"), ("2", "Two"), ("3", "Three")])
self.assertFalse(f.has_changed(None, None))
self.assertFalse(f.has_changed([], None))
- self.assertTrue(f.has_changed(None, ['1']))
- self.assertFalse(f.has_changed([1, 2], ['1', '2']))
- self.assertFalse(f.has_changed([2, 1], ['1', '2']))
- self.assertTrue(f.has_changed([1, 2], ['1']))
- self.assertTrue(f.has_changed([1, 2], ['1', '3']))
+ self.assertTrue(f.has_changed(None, ["1"]))
+ self.assertFalse(f.has_changed([1, 2], ["1", "2"]))
+ self.assertFalse(f.has_changed([2, 1], ["1", "2"]))
+ self.assertTrue(f.has_changed([1, 2], ["1"]))
+ self.assertTrue(f.has_changed([1, 2], ["1", "3"]))
def test_disabled_has_changed(self):
- f = MultipleChoiceField(choices=[('1', 'One'), ('2', 'Two')], disabled=True)
- self.assertIs(f.has_changed('x', 'y'), False)
+ f = MultipleChoiceField(choices=[("1", "One"), ("2", "Two")], disabled=True)
+ self.assertIs(f.has_changed("x", "y"), False)
diff --git a/tests/forms_tests/field_tests/test_multivaluefield.py b/tests/forms_tests/field_tests/test_multivaluefield.py
index 449bf16d19..88f7490013 100644
--- a/tests/forms_tests/field_tests/test_multivaluefield.py
+++ b/tests/forms_tests/field_tests/test_multivaluefield.py
@@ -2,17 +2,24 @@ from datetime import datetime
from django.core.exceptions import ValidationError
from django.forms import (
- CharField, Form, MultipleChoiceField, MultiValueField, MultiWidget,
- SelectMultiple, SplitDateTimeField, SplitDateTimeWidget, TextInput,
+ CharField,
+ Form,
+ MultipleChoiceField,
+ MultiValueField,
+ MultiWidget,
+ SelectMultiple,
+ SplitDateTimeField,
+ SplitDateTimeWidget,
+ TextInput,
)
from django.test import SimpleTestCase
-beatles = (('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))
+beatles = (("J", "John"), ("P", "Paul"), ("G", "George"), ("R", "Ringo"))
class PartiallyRequiredField(MultiValueField):
def compress(self, data_list):
- return ','.join(data_list) if data_list else None
+ return ",".join(data_list) if data_list else None
class PartiallyRequiredForm(Form):
@@ -35,7 +42,7 @@ class ComplexMultiWidget(MultiWidget):
def decompress(self, value):
if value:
- data = value.split(',')
+ data = value.split(",")
return [
data[0],
list(data[1]),
@@ -55,7 +62,7 @@ class ComplexField(MultiValueField):
def compress(self, data_list):
if data_list:
- return '%s,%s,%s' % (data_list[0], ''.join(data_list[1]), data_list[2])
+ return "%s,%s,%s" % (data_list[0], "".join(data_list[1]), data_list[2])
return None
@@ -64,7 +71,6 @@ class ComplexFieldForm(Form):
class MultiValueFieldTest(SimpleTestCase):
-
@classmethod
def setUpClass(cls):
cls.field = ComplexField(widget=ComplexMultiWidget())
@@ -72,8 +78,8 @@ class MultiValueFieldTest(SimpleTestCase):
def test_clean(self):
self.assertEqual(
- self.field.clean(['some text', ['J', 'P'], ['2007-04-25', '6:24:00']]),
- 'some text,JP,2007-04-25 06:24:00',
+ self.field.clean(["some text", ["J", "P"], ["2007-04-25", "6:24:00"]]),
+ "some text,JP,2007-04-25 06:24:00",
)
def test_clean_disabled_multivalue(self):
@@ -81,20 +87,20 @@ class MultiValueFieldTest(SimpleTestCase):
f = ComplexField(disabled=True, widget=ComplexMultiWidget)
inputs = (
- 'some text,JP,2007-04-25 06:24:00',
- ['some text', ['J', 'P'], ['2007-04-25', '6:24:00']],
+ "some text,JP,2007-04-25 06:24:00",
+ ["some text", ["J", "P"], ["2007-04-25", "6:24:00"]],
)
for data in inputs:
with self.subTest(data=data):
- form = ComplexFieldForm({}, initial={'f': data})
+ form = ComplexFieldForm({}, initial={"f": data})
form.full_clean()
self.assertEqual(form.errors, {})
- self.assertEqual(form.cleaned_data, {'f': inputs[0]})
+ self.assertEqual(form.cleaned_data, {"f": inputs[0]})
def test_bad_choice(self):
msg = "'Select a valid choice. X is not one of the available choices.'"
with self.assertRaisesMessage(ValidationError, msg):
- self.field.clean(['some text', ['X'], ['2007-04-25', '6:24:00']])
+ self.field.clean(["some text", ["X"], ["2007-04-25", "6:24:00"]])
def test_no_value(self):
"""
@@ -102,39 +108,49 @@ class MultiValueFieldTest(SimpleTestCase):
"""
msg = "'This field is required.'"
with self.assertRaisesMessage(ValidationError, msg):
- self.field.clean(['some text', ['JP']])
+ self.field.clean(["some text", ["JP"]])
def test_has_changed_no_initial(self):
- self.assertTrue(self.field.has_changed(None, ['some text', ['J', 'P'], ['2007-04-25', '6:24:00']]))
+ self.assertTrue(
+ self.field.has_changed(
+ None, ["some text", ["J", "P"], ["2007-04-25", "6:24:00"]]
+ )
+ )
def test_has_changed_same(self):
- self.assertFalse(self.field.has_changed(
- 'some text,JP,2007-04-25 06:24:00',
- ['some text', ['J', 'P'], ['2007-04-25', '6:24:00']],
- ))
+ self.assertFalse(
+ self.field.has_changed(
+ "some text,JP,2007-04-25 06:24:00",
+ ["some text", ["J", "P"], ["2007-04-25", "6:24:00"]],
+ )
+ )
def test_has_changed_first_widget(self):
"""
Test when the first widget's data has changed.
"""
- self.assertTrue(self.field.has_changed(
- 'some text,JP,2007-04-25 06:24:00',
- ['other text', ['J', 'P'], ['2007-04-25', '6:24:00']],
- ))
+ self.assertTrue(
+ self.field.has_changed(
+ "some text,JP,2007-04-25 06:24:00",
+ ["other text", ["J", "P"], ["2007-04-25", "6:24:00"]],
+ )
+ )
def test_has_changed_last_widget(self):
"""
Test when the last widget's data has changed. This ensures that it is
not short circuiting while testing the widgets.
"""
- self.assertTrue(self.field.has_changed(
- 'some text,JP,2007-04-25 06:24:00',
- ['some text', ['J', 'P'], ['2009-04-25', '11:44:00']],
- ))
+ self.assertTrue(
+ self.field.has_changed(
+ "some text,JP,2007-04-25 06:24:00",
+ ["some text", ["J", "P"], ["2009-04-25", "11:44:00"]],
+ )
+ )
def test_disabled_has_changed(self):
f = MultiValueField(fields=(CharField(), CharField()), disabled=True)
- self.assertIs(f.has_changed(['x', 'x'], ['y', 'y']), False)
+ self.assertIs(f.has_changed(["x", "x"], ["y", "y"]), False)
def test_form_as_table(self):
form = ComplexFieldForm()
@@ -155,12 +171,14 @@ class MultiValueFieldTest(SimpleTestCase):
)
def test_form_as_table_data(self):
- form = ComplexFieldForm({
- 'field1_0': 'some text',
- 'field1_1': ['J', 'P'],
- 'field1_2_0': '2007-04-25',
- 'field1_2_1': '06:24:00',
- })
+ form = ComplexFieldForm(
+ {
+ "field1_0": "some text",
+ "field1_1": ["J", "P"],
+ "field1_2_0": "2007-04-25",
+ "field1_2_1": "06:24:00",
+ }
+ )
self.assertHTMLEqual(
form.as_table(),
"""
@@ -178,19 +196,26 @@ class MultiValueFieldTest(SimpleTestCase):
)
def test_form_cleaned_data(self):
- form = ComplexFieldForm({
- 'field1_0': 'some text',
- 'field1_1': ['J', 'P'],
- 'field1_2_0': '2007-04-25',
- 'field1_2_1': '06:24:00',
- })
+ form = ComplexFieldForm(
+ {
+ "field1_0": "some text",
+ "field1_1": ["J", "P"],
+ "field1_2_0": "2007-04-25",
+ "field1_2_1": "06:24:00",
+ }
+ )
form.is_valid()
- self.assertEqual(form.cleaned_data['field1'], 'some text,JP,2007-04-25 06:24:00')
+ self.assertEqual(
+ form.cleaned_data["field1"], "some text,JP,2007-04-25 06:24:00"
+ )
def test_render_required_attributes(self):
- form = PartiallyRequiredForm({'f_0': 'Hello', 'f_1': ''})
+ form = PartiallyRequiredForm({"f_0": "Hello", "f_1": ""})
self.assertTrue(form.is_valid())
- self.assertInHTML('<input type="text" name="f_0" value="Hello" required id="id_f_0">', form.as_p())
+ self.assertInHTML(
+ '<input type="text" name="f_0" value="Hello" required id="id_f_0">',
+ form.as_p(),
+ )
self.assertInHTML('<input type="text" name="f_1" id="id_f_1">', form.as_p())
- form = PartiallyRequiredForm({'f_0': '', 'f_1': ''})
+ form = PartiallyRequiredForm({"f_0": "", "f_1": ""})
self.assertFalse(form.is_valid())
diff --git a/tests/forms_tests/field_tests/test_nullbooleanfield.py b/tests/forms_tests/field_tests/test_nullbooleanfield.py
index 55812612c9..5b632c8de3 100644
--- a/tests/forms_tests/field_tests/test_nullbooleanfield.py
+++ b/tests/forms_tests/field_tests/test_nullbooleanfield.py
@@ -5,56 +5,60 @@ from . import FormFieldAssertionsMixin
class NullBooleanFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
-
def test_nullbooleanfield_clean(self):
f = NullBooleanField()
- self.assertIsNone(f.clean(''))
+ self.assertIsNone(f.clean(""))
self.assertTrue(f.clean(True))
self.assertFalse(f.clean(False))
self.assertIsNone(f.clean(None))
- self.assertFalse(f.clean('0'))
- self.assertTrue(f.clean('1'))
- self.assertIsNone(f.clean('2'))
- self.assertIsNone(f.clean('3'))
- self.assertIsNone(f.clean('hello'))
- self.assertTrue(f.clean('true'))
- self.assertFalse(f.clean('false'))
+ self.assertFalse(f.clean("0"))
+ self.assertTrue(f.clean("1"))
+ self.assertIsNone(f.clean("2"))
+ self.assertIsNone(f.clean("3"))
+ self.assertIsNone(f.clean("hello"))
+ self.assertTrue(f.clean("true"))
+ self.assertFalse(f.clean("false"))
def test_nullbooleanfield_2(self):
# The internal value is preserved if using HiddenInput (#7753).
class HiddenNullBooleanForm(Form):
hidden_nullbool1 = NullBooleanField(widget=HiddenInput, initial=True)
hidden_nullbool2 = NullBooleanField(widget=HiddenInput, initial=False)
+
f = HiddenNullBooleanForm()
self.assertHTMLEqual(
'<input type="hidden" name="hidden_nullbool1" value="True" id="id_hidden_nullbool1">'
'<input type="hidden" name="hidden_nullbool2" value="False" id="id_hidden_nullbool2">',
- str(f)
+ str(f),
)
def test_nullbooleanfield_3(self):
class HiddenNullBooleanForm(Form):
hidden_nullbool1 = NullBooleanField(widget=HiddenInput, initial=True)
hidden_nullbool2 = NullBooleanField(widget=HiddenInput, initial=False)
- f = HiddenNullBooleanForm({'hidden_nullbool1': 'True', 'hidden_nullbool2': 'False'})
+
+ f = HiddenNullBooleanForm(
+ {"hidden_nullbool1": "True", "hidden_nullbool2": "False"}
+ )
self.assertIsNone(f.full_clean())
- self.assertTrue(f.cleaned_data['hidden_nullbool1'])
- self.assertFalse(f.cleaned_data['hidden_nullbool2'])
+ self.assertTrue(f.cleaned_data["hidden_nullbool1"])
+ self.assertFalse(f.cleaned_data["hidden_nullbool2"])
def test_nullbooleanfield_4(self):
# Make sure we're compatible with MySQL, which uses 0 and 1 for its
# boolean values (#9609).
- NULLBOOL_CHOICES = (('1', 'Yes'), ('0', 'No'), ('', 'Unknown'))
+ NULLBOOL_CHOICES = (("1", "Yes"), ("0", "No"), ("", "Unknown"))
class MySQLNullBooleanForm(Form):
nullbool0 = NullBooleanField(widget=RadioSelect(choices=NULLBOOL_CHOICES))
nullbool1 = NullBooleanField(widget=RadioSelect(choices=NULLBOOL_CHOICES))
nullbool2 = NullBooleanField(widget=RadioSelect(choices=NULLBOOL_CHOICES))
- f = MySQLNullBooleanForm({'nullbool0': '1', 'nullbool1': '0', 'nullbool2': ''})
+
+ f = MySQLNullBooleanForm({"nullbool0": "1", "nullbool1": "0", "nullbool2": ""})
self.assertIsNone(f.full_clean())
- self.assertTrue(f.cleaned_data['nullbool0'])
- self.assertFalse(f.cleaned_data['nullbool1'])
- self.assertIsNone(f.cleaned_data['nullbool2'])
+ self.assertTrue(f.cleaned_data["nullbool0"])
+ self.assertFalse(f.cleaned_data["nullbool1"])
+ self.assertIsNone(f.cleaned_data["nullbool2"])
def test_nullbooleanfield_changed(self):
f = NullBooleanField()
@@ -66,9 +70,9 @@ class NullBooleanFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
self.assertTrue(f.has_changed(True, None))
self.assertTrue(f.has_changed(True, False))
# HiddenInput widget sends string values for boolean but doesn't clean them in value_from_datadict
- self.assertFalse(f.has_changed(False, 'False'))
- self.assertFalse(f.has_changed(True, 'True'))
- self.assertFalse(f.has_changed(None, ''))
- self.assertTrue(f.has_changed(False, 'True'))
- self.assertTrue(f.has_changed(True, 'False'))
- self.assertTrue(f.has_changed(None, 'False'))
+ self.assertFalse(f.has_changed(False, "False"))
+ self.assertFalse(f.has_changed(True, "True"))
+ self.assertFalse(f.has_changed(None, ""))
+ self.assertTrue(f.has_changed(False, "True"))
+ self.assertTrue(f.has_changed(True, "False"))
+ self.assertTrue(f.has_changed(None, "False"))
diff --git a/tests/forms_tests/field_tests/test_regexfield.py b/tests/forms_tests/field_tests/test_regexfield.py
index 80d0f1c7cd..9a2b1387f6 100644
--- a/tests/forms_tests/field_tests/test_regexfield.py
+++ b/tests/forms_tests/field_tests/test_regexfield.py
@@ -6,80 +6,84 @@ from django.test import SimpleTestCase
class RegexFieldTest(SimpleTestCase):
-
def test_regexfield_1(self):
- f = RegexField('^[0-9][A-F][0-9]$')
- self.assertEqual('2A2', f.clean('2A2'))
- self.assertEqual('3F3', f.clean('3F3'))
+ f = RegexField("^[0-9][A-F][0-9]$")
+ self.assertEqual("2A2", f.clean("2A2"))
+ self.assertEqual("3F3", f.clean("3F3"))
with self.assertRaisesMessage(ValidationError, "'Enter a valid value.'"):
- f.clean('3G3')
+ f.clean("3G3")
with self.assertRaisesMessage(ValidationError, "'Enter a valid value.'"):
- f.clean(' 2A2')
+ f.clean(" 2A2")
with self.assertRaisesMessage(ValidationError, "'Enter a valid value.'"):
- f.clean('2A2 ')
+ f.clean("2A2 ")
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('')
+ f.clean("")
def test_regexfield_2(self):
- f = RegexField('^[0-9][A-F][0-9]$', required=False)
- self.assertEqual('2A2', f.clean('2A2'))
- self.assertEqual('3F3', f.clean('3F3'))
+ f = RegexField("^[0-9][A-F][0-9]$", required=False)
+ self.assertEqual("2A2", f.clean("2A2"))
+ self.assertEqual("3F3", f.clean("3F3"))
with self.assertRaisesMessage(ValidationError, "'Enter a valid value.'"):
- f.clean('3G3')
- self.assertEqual('', f.clean(''))
+ f.clean("3G3")
+ self.assertEqual("", f.clean(""))
def test_regexfield_3(self):
- f = RegexField(re.compile('^[0-9][A-F][0-9]$'))
- self.assertEqual('2A2', f.clean('2A2'))
- self.assertEqual('3F3', f.clean('3F3'))
+ f = RegexField(re.compile("^[0-9][A-F][0-9]$"))
+ self.assertEqual("2A2", f.clean("2A2"))
+ self.assertEqual("3F3", f.clean("3F3"))
with self.assertRaisesMessage(ValidationError, "'Enter a valid value.'"):
- f.clean('3G3')
+ f.clean("3G3")
with self.assertRaisesMessage(ValidationError, "'Enter a valid value.'"):
- f.clean(' 2A2')
+ f.clean(" 2A2")
with self.assertRaisesMessage(ValidationError, "'Enter a valid value.'"):
- f.clean('2A2 ')
+ f.clean("2A2 ")
def test_regexfield_4(self):
- f = RegexField('^[0-9]+$', min_length=5, max_length=10)
- with self.assertRaisesMessage(ValidationError, "'Ensure this value has at least 5 characters (it has 3).'"):
- f.clean('123')
+ f = RegexField("^[0-9]+$", min_length=5, max_length=10)
+ with self.assertRaisesMessage(
+ ValidationError, "'Ensure this value has at least 5 characters (it has 3).'"
+ ):
+ f.clean("123")
with self.assertRaisesMessage(
ValidationError,
"'Ensure this value has at least 5 characters (it has 3).', "
"'Enter a valid value.'",
):
- f.clean('abc')
- self.assertEqual('12345', f.clean('12345'))
- self.assertEqual('1234567890', f.clean('1234567890'))
- with self.assertRaisesMessage(ValidationError, "'Ensure this value has at most 10 characters (it has 11).'"):
- f.clean('12345678901')
+ f.clean("abc")
+ self.assertEqual("12345", f.clean("12345"))
+ self.assertEqual("1234567890", f.clean("1234567890"))
+ with self.assertRaisesMessage(
+ ValidationError,
+ "'Ensure this value has at most 10 characters (it has 11).'",
+ ):
+ f.clean("12345678901")
with self.assertRaisesMessage(ValidationError, "'Enter a valid value.'"):
- f.clean('12345a')
+ f.clean("12345a")
def test_regexfield_unicode_characters(self):
- f = RegexField(r'^\w+$')
- self.assertEqual('éèøçÎÎ你好', f.clean('éèøçÎÎ你好'))
+ f = RegexField(r"^\w+$")
+ self.assertEqual("éèøçÎÎ你好", f.clean("éèøçÎÎ你好"))
def test_change_regex_after_init(self):
- f = RegexField('^[a-z]+$')
- f.regex = '^[0-9]+$'
- self.assertEqual('1234', f.clean('1234'))
+ f = RegexField("^[a-z]+$")
+ f.regex = "^[0-9]+$"
+ self.assertEqual("1234", f.clean("1234"))
with self.assertRaisesMessage(ValidationError, "'Enter a valid value.'"):
- f.clean('abcd')
+ f.clean("abcd")
def test_get_regex(self):
- f = RegexField('^[a-z]+$')
- self.assertEqual(f.regex, re.compile('^[a-z]+$'))
+ f = RegexField("^[a-z]+$")
+ self.assertEqual(f.regex, re.compile("^[a-z]+$"))
def test_regexfield_strip(self):
- f = RegexField('^[a-z]+$', strip=True)
- self.assertEqual(f.clean(' a'), 'a')
- self.assertEqual(f.clean('a '), 'a')
+ f = RegexField("^[a-z]+$", strip=True)
+ self.assertEqual(f.clean(" a"), "a")
+ self.assertEqual(f.clean("a "), "a")
def test_empty_value(self):
- f = RegexField('', required=False)
- self.assertEqual(f.clean(''), '')
- self.assertEqual(f.clean(None), '')
- f = RegexField('', empty_value=None, required=False)
- self.assertIsNone(f.clean(''))
+ f = RegexField("", required=False)
+ self.assertEqual(f.clean(""), "")
+ self.assertEqual(f.clean(None), "")
+ f = RegexField("", empty_value=None, required=False)
+ self.assertIsNone(f.clean(""))
self.assertIsNone(f.clean(None))
diff --git a/tests/forms_tests/field_tests/test_slugfield.py b/tests/forms_tests/field_tests/test_slugfield.py
index 6d766e8af5..d796a2c3aa 100644
--- a/tests/forms_tests/field_tests/test_slugfield.py
+++ b/tests/forms_tests/field_tests/test_slugfield.py
@@ -3,25 +3,24 @@ from django.test import SimpleTestCase
class SlugFieldTest(SimpleTestCase):
-
def test_slugfield_normalization(self):
f = SlugField()
- self.assertEqual(f.clean(' aa-bb-cc '), 'aa-bb-cc')
+ self.assertEqual(f.clean(" aa-bb-cc "), "aa-bb-cc")
def test_slugfield_unicode_normalization(self):
f = SlugField(allow_unicode=True)
- self.assertEqual(f.clean('a'), 'a')
- self.assertEqual(f.clean('1'), '1')
- self.assertEqual(f.clean('a1'), 'a1')
- self.assertEqual(f.clean('你好'), '你好')
- self.assertEqual(f.clean(' 你-好 '), '你-好')
- self.assertEqual(f.clean('ıçğüş'), 'ıçğüş')
- self.assertEqual(f.clean('foo-ıç-bar'), 'foo-ıç-bar')
+ self.assertEqual(f.clean("a"), "a")
+ self.assertEqual(f.clean("1"), "1")
+ self.assertEqual(f.clean("a1"), "a1")
+ self.assertEqual(f.clean("你好"), "你好")
+ self.assertEqual(f.clean(" 你-好 "), "你-好")
+ self.assertEqual(f.clean("ıçğüş"), "ıçğüş")
+ self.assertEqual(f.clean("foo-ıç-bar"), "foo-ıç-bar")
def test_empty_value(self):
f = SlugField(required=False)
- self.assertEqual(f.clean(''), '')
- self.assertEqual(f.clean(None), '')
+ self.assertEqual(f.clean(""), "")
+ self.assertEqual(f.clean(None), "")
f = SlugField(required=False, empty_value=None)
- self.assertIsNone(f.clean(''))
+ self.assertIsNone(f.clean(""))
self.assertIsNone(f.clean(None))
diff --git a/tests/forms_tests/field_tests/test_splitdatetimefield.py b/tests/forms_tests/field_tests/test_splitdatetimefield.py
index bf20587682..788ca592fa 100644
--- a/tests/forms_tests/field_tests/test_splitdatetimefield.py
+++ b/tests/forms_tests/field_tests/test_splitdatetimefield.py
@@ -7,59 +7,78 @@ from django.test import SimpleTestCase
class SplitDateTimeFieldTest(SimpleTestCase):
-
def test_splitdatetimefield_1(self):
f = SplitDateTimeField()
self.assertIsInstance(f.widget, SplitDateTimeWidget)
self.assertEqual(
datetime.datetime(2006, 1, 10, 7, 30),
- f.clean([datetime.date(2006, 1, 10), datetime.time(7, 30)])
+ f.clean([datetime.date(2006, 1, 10), datetime.time(7, 30)]),
)
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(None)
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('')
+ f.clean("")
with self.assertRaisesMessage(ValidationError, "'Enter a list of values.'"):
- f.clean('hello')
- with self.assertRaisesMessage(ValidationError, "'Enter a valid date.', 'Enter a valid time.'"):
- f.clean(['hello', 'there'])
+ f.clean("hello")
+ with self.assertRaisesMessage(
+ ValidationError, "'Enter a valid date.', 'Enter a valid time.'"
+ ):
+ f.clean(["hello", "there"])
with self.assertRaisesMessage(ValidationError, "'Enter a valid time.'"):
- f.clean(['2006-01-10', 'there'])
+ f.clean(["2006-01-10", "there"])
with self.assertRaisesMessage(ValidationError, "'Enter a valid date.'"):
- f.clean(['hello', '07:30'])
+ f.clean(["hello", "07:30"])
def test_splitdatetimefield_2(self):
f = SplitDateTimeField(required=False)
self.assertEqual(
datetime.datetime(2006, 1, 10, 7, 30),
- f.clean([datetime.date(2006, 1, 10), datetime.time(7, 30)])
+ f.clean([datetime.date(2006, 1, 10), datetime.time(7, 30)]),
+ )
+ self.assertEqual(
+ datetime.datetime(2006, 1, 10, 7, 30), f.clean(["2006-01-10", "07:30"])
)
- self.assertEqual(datetime.datetime(2006, 1, 10, 7, 30), f.clean(['2006-01-10', '07:30']))
self.assertIsNone(f.clean(None))
- self.assertIsNone(f.clean(''))
- self.assertIsNone(f.clean(['']))
- self.assertIsNone(f.clean(['', '']))
+ self.assertIsNone(f.clean(""))
+ self.assertIsNone(f.clean([""]))
+ self.assertIsNone(f.clean(["", ""]))
with self.assertRaisesMessage(ValidationError, "'Enter a list of values.'"):
- f.clean('hello')
- with self.assertRaisesMessage(ValidationError, "'Enter a valid date.', 'Enter a valid time.'"):
- f.clean(['hello', 'there'])
+ f.clean("hello")
+ with self.assertRaisesMessage(
+ ValidationError, "'Enter a valid date.', 'Enter a valid time.'"
+ ):
+ f.clean(["hello", "there"])
with self.assertRaisesMessage(ValidationError, "'Enter a valid time.'"):
- f.clean(['2006-01-10', 'there'])
+ f.clean(["2006-01-10", "there"])
with self.assertRaisesMessage(ValidationError, "'Enter a valid date.'"):
- f.clean(['hello', '07:30'])
+ f.clean(["hello", "07:30"])
with self.assertRaisesMessage(ValidationError, "'Enter a valid time.'"):
- f.clean(['2006-01-10', ''])
+ f.clean(["2006-01-10", ""])
with self.assertRaisesMessage(ValidationError, "'Enter a valid time.'"):
- f.clean(['2006-01-10'])
+ f.clean(["2006-01-10"])
with self.assertRaisesMessage(ValidationError, "'Enter a valid date.'"):
- f.clean(['', '07:30'])
+ f.clean(["", "07:30"])
def test_splitdatetimefield_changed(self):
- f = SplitDateTimeField(input_date_formats=['%d/%m/%Y'])
- self.assertFalse(f.has_changed(['11/01/2012', '09:18:15'], ['11/01/2012', '09:18:15']))
- self.assertTrue(f.has_changed(datetime.datetime(2008, 5, 6, 12, 40, 00), ['2008-05-06', '12:40:00']))
- self.assertFalse(f.has_changed(datetime.datetime(2008, 5, 6, 12, 40, 00), ['06/05/2008', '12:40']))
- self.assertTrue(f.has_changed(datetime.datetime(2008, 5, 6, 12, 40, 00), ['06/05/2008', '12:41']))
+ f = SplitDateTimeField(input_date_formats=["%d/%m/%Y"])
+ self.assertFalse(
+ f.has_changed(["11/01/2012", "09:18:15"], ["11/01/2012", "09:18:15"])
+ )
+ self.assertTrue(
+ f.has_changed(
+ datetime.datetime(2008, 5, 6, 12, 40, 00), ["2008-05-06", "12:40:00"]
+ )
+ )
+ self.assertFalse(
+ f.has_changed(
+ datetime.datetime(2008, 5, 6, 12, 40, 00), ["06/05/2008", "12:40"]
+ )
+ )
+ self.assertTrue(
+ f.has_changed(
+ datetime.datetime(2008, 5, 6, 12, 40, 00), ["06/05/2008", "12:41"]
+ )
+ )
def test_form_as_table(self):
class TestForm(Form):
@@ -68,8 +87,8 @@ class SplitDateTimeFieldTest(SimpleTestCase):
f = TestForm()
self.assertHTMLEqual(
f.as_table(),
- '<tr><th><label>Datetime:</label></th><td>'
+ "<tr><th><label>Datetime:</label></th><td>"
'<input type="text" name="datetime_0" required id="id_datetime_0">'
'<input type="text" name="datetime_1" required id="id_datetime_1">'
- '</td></tr>',
+ "</td></tr>",
)
diff --git a/tests/forms_tests/field_tests/test_timefield.py b/tests/forms_tests/field_tests/test_timefield.py
index a44b10fa07..fbe6a3cf31 100644
--- a/tests/forms_tests/field_tests/test_timefield.py
+++ b/tests/forms_tests/field_tests/test_timefield.py
@@ -8,39 +8,38 @@ from . import FormFieldAssertionsMixin
class TimeFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
-
def test_timefield_1(self):
f = TimeField()
self.assertEqual(datetime.time(14, 25), f.clean(datetime.time(14, 25)))
self.assertEqual(datetime.time(14, 25, 59), f.clean(datetime.time(14, 25, 59)))
- self.assertEqual(datetime.time(14, 25), f.clean('14:25'))
- self.assertEqual(datetime.time(14, 25, 59), f.clean('14:25:59'))
+ self.assertEqual(datetime.time(14, 25), f.clean("14:25"))
+ self.assertEqual(datetime.time(14, 25, 59), f.clean("14:25:59"))
with self.assertRaisesMessage(ValidationError, "'Enter a valid time.'"):
- f.clean('hello')
+ f.clean("hello")
with self.assertRaisesMessage(ValidationError, "'Enter a valid time.'"):
- f.clean('1:24 p.m.')
+ f.clean("1:24 p.m.")
def test_timefield_2(self):
- f = TimeField(input_formats=['%I:%M %p'])
+ f = TimeField(input_formats=["%I:%M %p"])
self.assertEqual(datetime.time(14, 25), f.clean(datetime.time(14, 25)))
self.assertEqual(datetime.time(14, 25, 59), f.clean(datetime.time(14, 25, 59)))
- self.assertEqual(datetime.time(4, 25), f.clean('4:25 AM'))
- self.assertEqual(datetime.time(16, 25), f.clean('4:25 PM'))
+ self.assertEqual(datetime.time(4, 25), f.clean("4:25 AM"))
+ self.assertEqual(datetime.time(16, 25), f.clean("4:25 PM"))
with self.assertRaisesMessage(ValidationError, "'Enter a valid time.'"):
- f.clean('14:30:45')
+ f.clean("14:30:45")
def test_timefield_3(self):
f = TimeField()
# Test whitespace stripping behavior (#5714)
- self.assertEqual(datetime.time(14, 25), f.clean(' 14:25 '))
- self.assertEqual(datetime.time(14, 25, 59), f.clean(' 14:25:59 '))
+ self.assertEqual(datetime.time(14, 25), f.clean(" 14:25 "))
+ self.assertEqual(datetime.time(14, 25, 59), f.clean(" 14:25:59 "))
with self.assertRaisesMessage(ValidationError, "'Enter a valid time.'"):
- f.clean(' ')
+ f.clean(" ")
def test_timefield_changed(self):
t1 = datetime.time(12, 51, 34, 482548)
t2 = datetime.time(12, 51)
- f = TimeField(input_formats=['%H:%M', '%H:%M %p'])
- self.assertTrue(f.has_changed(t1, '12:51'))
- self.assertFalse(f.has_changed(t2, '12:51'))
- self.assertFalse(f.has_changed(t2, '12:51 PM'))
+ f = TimeField(input_formats=["%H:%M", "%H:%M %p"])
+ self.assertTrue(f.has_changed(t1, "12:51"))
+ self.assertFalse(f.has_changed(t2, "12:51"))
+ self.assertFalse(f.has_changed(t2, "12:51 PM"))
diff --git a/tests/forms_tests/field_tests/test_typedchoicefield.py b/tests/forms_tests/field_tests/test_typedchoicefield.py
index 2c6cd265b5..52a83eca37 100644
--- a/tests/forms_tests/field_tests/test_typedchoicefield.py
+++ b/tests/forms_tests/field_tests/test_typedchoicefield.py
@@ -6,72 +6,84 @@ from django.test import SimpleTestCase
class TypedChoiceFieldTest(SimpleTestCase):
-
def test_typedchoicefield_1(self):
f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int)
- self.assertEqual(1, f.clean('1'))
+ self.assertEqual(1, f.clean("1"))
msg = "'Select a valid choice. 2 is not one of the available choices.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('2')
+ f.clean("2")
def test_typedchoicefield_2(self):
# Different coercion, same validation.
f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=float)
- self.assertEqual(1.0, f.clean('1'))
+ self.assertEqual(1.0, f.clean("1"))
def test_typedchoicefield_3(self):
# This can also cause weirdness: be careful (bool(-1) == True, remember)
f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=bool)
- self.assertTrue(f.clean('-1'))
+ self.assertTrue(f.clean("-1"))
def test_typedchoicefield_4(self):
# Even more weirdness: if you have a valid choice but your coercion function
# can't coerce, you'll still get a validation error. Don't do this!
- f = TypedChoiceField(choices=[('A', 'A'), ('B', 'B')], coerce=int)
+ f = TypedChoiceField(choices=[("A", "A"), ("B", "B")], coerce=int)
msg = "'Select a valid choice. B is not one of the available choices.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('B')
+ f.clean("B")
# Required fields require values
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('')
+ f.clean("")
def test_typedchoicefield_5(self):
# Non-required fields aren't required
- f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int, required=False)
- self.assertEqual('', f.clean(''))
+ f = TypedChoiceField(
+ choices=[(1, "+1"), (-1, "-1")], coerce=int, required=False
+ )
+ self.assertEqual("", f.clean(""))
# If you want cleaning an empty value to return a different type, tell the field
def test_typedchoicefield_6(self):
- f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int, required=False, empty_value=None)
- self.assertIsNone(f.clean(''))
+ f = TypedChoiceField(
+ choices=[(1, "+1"), (-1, "-1")],
+ coerce=int,
+ required=False,
+ empty_value=None,
+ )
+ self.assertIsNone(f.clean(""))
def test_typedchoicefield_has_changed(self):
# has_changed should not trigger required validation
f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int, required=True)
- self.assertFalse(f.has_changed(None, ''))
- self.assertFalse(f.has_changed(1, '1'))
- self.assertFalse(f.has_changed('1', '1'))
+ self.assertFalse(f.has_changed(None, ""))
+ self.assertFalse(f.has_changed(1, "1"))
+ self.assertFalse(f.has_changed("1", "1"))
f = TypedChoiceField(
- choices=[('', '---------'), ('a', "a"), ('b', "b")], coerce=str,
- required=False, initial=None, empty_value=None,
+ choices=[("", "---------"), ("a", "a"), ("b", "b")],
+ coerce=str,
+ required=False,
+ initial=None,
+ empty_value=None,
)
- self.assertFalse(f.has_changed(None, ''))
- self.assertTrue(f.has_changed('', 'a'))
- self.assertFalse(f.has_changed('a', 'a'))
+ self.assertFalse(f.has_changed(None, ""))
+ self.assertTrue(f.has_changed("", "a"))
+ self.assertFalse(f.has_changed("a", "a"))
def test_typedchoicefield_special_coerce(self):
"""
A coerce function which results in a value not present in choices
should raise an appropriate error (#21397).
"""
+
def coerce_func(val):
- return decimal.Decimal('1.%s' % val)
+ return decimal.Decimal("1.%s" % val)
- f = TypedChoiceField(choices=[(1, "1"), (2, "2")], coerce=coerce_func, required=True)
- self.assertEqual(decimal.Decimal('1.2'), f.clean('2'))
+ f = TypedChoiceField(
+ choices=[(1, "1"), (2, "2")], coerce=coerce_func, required=True
+ )
+ self.assertEqual(decimal.Decimal("1.2"), f.clean("2"))
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('')
+ f.clean("")
msg = "'Select a valid choice. 3 is not one of the available choices.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('3')
+ f.clean("3")
diff --git a/tests/forms_tests/field_tests/test_typedmultiplechoicefield.py b/tests/forms_tests/field_tests/test_typedmultiplechoicefield.py
index 1c97676a87..6810f1ed19 100644
--- a/tests/forms_tests/field_tests/test_typedmultiplechoicefield.py
+++ b/tests/forms_tests/field_tests/test_typedmultiplechoicefield.py
@@ -6,70 +6,80 @@ from django.test import SimpleTestCase
class TypedMultipleChoiceFieldTest(SimpleTestCase):
-
def test_typedmultiplechoicefield_1(self):
f = TypedMultipleChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int)
- self.assertEqual([1], f.clean(['1']))
+ self.assertEqual([1], f.clean(["1"]))
msg = "'Select a valid choice. 2 is not one of the available choices.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean(['2'])
+ f.clean(["2"])
def test_typedmultiplechoicefield_2(self):
# Different coercion, same validation.
f = TypedMultipleChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=float)
- self.assertEqual([1.0], f.clean(['1']))
+ self.assertEqual([1.0], f.clean(["1"]))
def test_typedmultiplechoicefield_3(self):
# This can also cause weirdness: be careful (bool(-1) == True, remember)
f = TypedMultipleChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=bool)
- self.assertEqual([True], f.clean(['-1']))
+ self.assertEqual([True], f.clean(["-1"]))
def test_typedmultiplechoicefield_4(self):
f = TypedMultipleChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int)
- self.assertEqual([1, -1], f.clean(['1', '-1']))
+ self.assertEqual([1, -1], f.clean(["1", "-1"]))
msg = "'Select a valid choice. 2 is not one of the available choices.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean(['1', '2'])
+ f.clean(["1", "2"])
def test_typedmultiplechoicefield_5(self):
# Even more weirdness: if you have a valid choice but your coercion function
# can't coerce, you'll still get a validation error. Don't do this!
- f = TypedMultipleChoiceField(choices=[('A', 'A'), ('B', 'B')], coerce=int)
+ f = TypedMultipleChoiceField(choices=[("A", "A"), ("B", "B")], coerce=int)
msg = "'Select a valid choice. B is not one of the available choices.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean(['B'])
+ f.clean(["B"])
# Required fields require values
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean([])
def test_typedmultiplechoicefield_6(self):
# Non-required fields aren't required
- f = TypedMultipleChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int, required=False)
+ f = TypedMultipleChoiceField(
+ choices=[(1, "+1"), (-1, "-1")], coerce=int, required=False
+ )
self.assertEqual([], f.clean([]))
def test_typedmultiplechoicefield_7(self):
# If you want cleaning an empty value to return a different type, tell the field
- f = TypedMultipleChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int, required=False, empty_value=None)
+ f = TypedMultipleChoiceField(
+ choices=[(1, "+1"), (-1, "-1")],
+ coerce=int,
+ required=False,
+ empty_value=None,
+ )
self.assertIsNone(f.clean([]))
def test_typedmultiplechoicefield_has_changed(self):
# has_changed should not trigger required validation
- f = TypedMultipleChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int, required=True)
- self.assertFalse(f.has_changed(None, ''))
+ f = TypedMultipleChoiceField(
+ choices=[(1, "+1"), (-1, "-1")], coerce=int, required=True
+ )
+ self.assertFalse(f.has_changed(None, ""))
def test_typedmultiplechoicefield_special_coerce(self):
"""
A coerce function which results in a value not present in choices
should raise an appropriate error (#21397).
"""
+
def coerce_func(val):
- return decimal.Decimal('1.%s' % val)
+ return decimal.Decimal("1.%s" % val)
f = TypedMultipleChoiceField(
- choices=[(1, "1"), (2, "2")], coerce=coerce_func, required=True)
- self.assertEqual([decimal.Decimal('1.2')], f.clean(['2']))
+ choices=[(1, "1"), (2, "2")], coerce=coerce_func, required=True
+ )
+ self.assertEqual([decimal.Decimal("1.2")], f.clean(["2"]))
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean([])
msg = "'Select a valid choice. 3 is not one of the available choices.'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean(['3'])
+ f.clean(["3"])
diff --git a/tests/forms_tests/field_tests/test_urlfield.py b/tests/forms_tests/field_tests/test_urlfield.py
index 187d44a050..042a3bf586 100644
--- a/tests/forms_tests/field_tests/test_urlfield.py
+++ b/tests/forms_tests/field_tests/test_urlfield.py
@@ -6,14 +6,13 @@ from . import FormFieldAssertionsMixin
class URLFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
-
def test_urlfield_widget(self):
f = URLField()
self.assertWidgetRendersTo(f, '<input type="url" name="f" id="id_f" required>')
def test_urlfield_widget_max_min_length(self):
f = URLField(min_length=15, max_length=20)
- self.assertEqual('http://example.com', f.clean('http://example.com'))
+ self.assertEqual("http://example.com", f.clean("http://example.com"))
self.assertWidgetRendersTo(
f,
'<input id="id_f" type="url" name="f" maxlength="20" '
@@ -21,55 +20,58 @@ class URLFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
)
msg = "'Ensure this value has at least 15 characters (it has 12).'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('http://f.com')
+ f.clean("http://f.com")
msg = "'Ensure this value has at most 20 characters (it has 37).'"
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('http://abcdefghijklmnopqrstuvwxyz.com')
+ f.clean("http://abcdefghijklmnopqrstuvwxyz.com")
def test_urlfield_clean(self):
f = URLField(required=False)
tests = [
- ('http://localhost', 'http://localhost'),
- ('http://example.com', 'http://example.com'),
- ('http://example.com/test', 'http://example.com/test'),
- ('http://example.com.', 'http://example.com.'),
- ('http://www.example.com', 'http://www.example.com'),
- ('http://www.example.com:8000/test', 'http://www.example.com:8000/test'),
+ ("http://localhost", "http://localhost"),
+ ("http://example.com", "http://example.com"),
+ ("http://example.com/test", "http://example.com/test"),
+ ("http://example.com.", "http://example.com."),
+ ("http://www.example.com", "http://www.example.com"),
+ ("http://www.example.com:8000/test", "http://www.example.com:8000/test"),
(
- 'http://example.com?some_param=some_value',
- 'http://example.com?some_param=some_value',
+ "http://example.com?some_param=some_value",
+ "http://example.com?some_param=some_value",
),
- ('valid-with-hyphens.com', 'http://valid-with-hyphens.com'),
- ('subdomain.domain.com', 'http://subdomain.domain.com'),
- ('http://200.8.9.10', 'http://200.8.9.10'),
- ('http://200.8.9.10:8000/test', 'http://200.8.9.10:8000/test'),
- ('http://valid-----hyphens.com', 'http://valid-----hyphens.com'),
+ ("valid-with-hyphens.com", "http://valid-with-hyphens.com"),
+ ("subdomain.domain.com", "http://subdomain.domain.com"),
+ ("http://200.8.9.10", "http://200.8.9.10"),
+ ("http://200.8.9.10:8000/test", "http://200.8.9.10:8000/test"),
+ ("http://valid-----hyphens.com", "http://valid-----hyphens.com"),
(
- 'http://some.idn.xyzäöüßabc.domain.com:123/blah',
- 'http://some.idn.xyz\xe4\xf6\xfc\xdfabc.domain.com:123/blah',
+ "http://some.idn.xyzäöüßabc.domain.com:123/blah",
+ "http://some.idn.xyz\xe4\xf6\xfc\xdfabc.domain.com:123/blah",
),
(
- 'www.example.com/s/http://code.djangoproject.com/ticket/13804',
- 'http://www.example.com/s/http://code.djangoproject.com/ticket/13804',
+ "www.example.com/s/http://code.djangoproject.com/ticket/13804",
+ "http://www.example.com/s/http://code.djangoproject.com/ticket/13804",
),
# Normalization.
- ('http://example.com/ ', 'http://example.com/'),
+ ("http://example.com/ ", "http://example.com/"),
# Valid IDN.
- ('http://עברית.idn.icann.org/', 'http://עברית.idn.icann.org/'),
- ('http://sãopaulo.com/', 'http://sãopaulo.com/'),
- ('http://sãopaulo.com.br/', 'http://sãopaulo.com.br/'),
- ('http://пример.испытание/', 'http://пример.испытание/'),
- ('http://مثال.إختبار/', 'http://مثال.إختبار/'),
- ('http://例子.测试/', 'http://例子.测试/'),
- ('http://例子.測試/', 'http://例子.測試/'),
- ('http://उदाहरण.परीक्षा/', 'http://उदाहरण.परीक्षा/',),
- ('http://例え.テスト/', 'http://例え.テスト/'),
- ('http://مثال.آزمایشی/', 'http://مثال.آزمایشی/'),
- ('http://실례.테스트/', 'http://실례.테스트/'),
- ('http://العربية.idn.icann.org/', 'http://العربية.idn.icann.org/'),
+ ("http://עברית.idn.icann.org/", "http://עברית.idn.icann.org/"),
+ ("http://sãopaulo.com/", "http://sãopaulo.com/"),
+ ("http://sãopaulo.com.br/", "http://sãopaulo.com.br/"),
+ ("http://пример.испытание/", "http://пример.испытание/"),
+ ("http://مثال.إختبار/", "http://مثال.إختبار/"),
+ ("http://例子.测试/", "http://例子.测试/"),
+ ("http://例子.測試/", "http://例子.測試/"),
+ (
+ "http://उदाहरण.परीक्षा/",
+ "http://उदाहरण.परीक्षा/",
+ ),
+ ("http://例え.テスト/", "http://例え.テスト/"),
+ ("http://مثال.آزمایشی/", "http://مثال.آزمایشی/"),
+ ("http://실례.테스트/", "http://실례.테스트/"),
+ ("http://العربية.idn.icann.org/", "http://العربية.idn.icann.org/"),
# IPv6.
- ('http://[12:34::3a53]/', 'http://[12:34::3a53]/'),
- ('http://[a34:9238::]:8080/', 'http://[a34:9238::]:8080/'),
+ ("http://[12:34::3a53]/", "http://[12:34::3a53]/"),
+ ("http://[a34:9238::]:8080/", "http://[a34:9238::]:8080/"),
]
for url, expected in tests:
with self.subTest(url=url):
@@ -78,32 +80,32 @@ class URLFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
def test_urlfield_clean_invalid(self):
f = URLField()
tests = [
- 'foo',
- 'com.',
- '.',
- 'http://',
- 'http://example',
- 'http://example.',
- 'http://.com',
- 'http://invalid-.com',
- 'http://-invalid.com',
- 'http://inv-.alid-.com',
- 'http://inv-.-alid.com',
- '[a',
- 'http://[a',
+ "foo",
+ "com.",
+ ".",
+ "http://",
+ "http://example",
+ "http://example.",
+ "http://.com",
+ "http://invalid-.com",
+ "http://-invalid.com",
+ "http://inv-.alid-.com",
+ "http://inv-.-alid.com",
+ "[a",
+ "http://[a",
# Non-string.
23,
# Hangs "forever" before fixing a catastrophic backtracking,
# see #11198.
- 'http://%s' % ('X' * 60,),
+ "http://%s" % ("X" * 60,),
# A second example, to make sure the problem is really addressed,
# even on domains that don't fail the domain label length check in
# the regex.
- 'http://%s' % ("X" * 200,),
+ "http://%s" % ("X" * 200,),
# urlsplit() raises ValueError.
- '////]@N.AN',
+ "////]@N.AN",
# Empty hostname.
- '#@A.bO',
+ "#@A.bO",
]
msg = "'Enter a valid URL.'"
for value in tests:
@@ -117,16 +119,16 @@ class URLFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
with self.assertRaisesMessage(ValidationError, msg):
f.clean(None)
with self.assertRaisesMessage(ValidationError, msg):
- f.clean('')
+ f.clean("")
def test_urlfield_clean_not_required(self):
f = URLField(required=False)
- self.assertEqual(f.clean(None), '')
- self.assertEqual(f.clean(''), '')
+ self.assertEqual(f.clean(None), "")
+ self.assertEqual(f.clean(""), "")
def test_urlfield_strip_on_none_value(self):
f = URLField(required=False, empty_value=None)
- self.assertIsNone(f.clean(''))
+ self.assertIsNone(f.clean(""))
self.assertIsNone(f.clean(None))
def test_urlfield_unable_to_set_strip_kwarg(self):
diff --git a/tests/forms_tests/field_tests/test_uuidfield.py b/tests/forms_tests/field_tests/test_uuidfield.py
index e1c1698d02..b039c4a0c3 100644
--- a/tests/forms_tests/field_tests/test_uuidfield.py
+++ b/tests/forms_tests/field_tests/test_uuidfield.py
@@ -6,28 +6,27 @@ from django.test import SimpleTestCase
class UUIDFieldTest(SimpleTestCase):
-
def test_uuidfield_1(self):
field = UUIDField()
- value = field.clean('550e8400e29b41d4a716446655440000')
- self.assertEqual(value, uuid.UUID('550e8400e29b41d4a716446655440000'))
+ value = field.clean("550e8400e29b41d4a716446655440000")
+ self.assertEqual(value, uuid.UUID("550e8400e29b41d4a716446655440000"))
def test_clean_value_with_dashes(self):
field = UUIDField()
- value = field.clean('550e8400-e29b-41d4-a716-446655440000')
- self.assertEqual(value, uuid.UUID('550e8400e29b41d4a716446655440000'))
+ value = field.clean("550e8400-e29b-41d4-a716-446655440000")
+ self.assertEqual(value, uuid.UUID("550e8400e29b41d4a716446655440000"))
def test_uuidfield_2(self):
field = UUIDField(required=False)
- self.assertIsNone(field.clean(''))
+ self.assertIsNone(field.clean(""))
self.assertIsNone(field.clean(None))
def test_uuidfield_3(self):
field = UUIDField()
- with self.assertRaisesMessage(ValidationError, 'Enter a valid UUID.'):
- field.clean('550e8400')
+ with self.assertRaisesMessage(ValidationError, "Enter a valid UUID."):
+ field.clean("550e8400")
def test_uuidfield_4(self):
field = UUIDField()
- value = field.prepare_value(uuid.UUID('550e8400e29b41d4a716446655440000'))
- self.assertEqual(value, '550e8400-e29b-41d4-a716-446655440000')
+ value = field.prepare_value(uuid.UUID("550e8400e29b41d4a716446655440000"))
+ self.assertEqual(value, "550e8400-e29b-41d4-a716-446655440000")
diff --git a/tests/forms_tests/models.py b/tests/forms_tests/models.py
index 23cabc2d84..ae212f332d 100644
--- a/tests/forms_tests/models.py
+++ b/tests/forms_tests/models.py
@@ -20,7 +20,7 @@ class BoundaryModel(models.Model):
class Defaults(models.Model):
- name = models.CharField(max_length=255, default='class default value')
+ name = models.CharField(max_length=255, default="class default value")
def_date = models.DateField(default=datetime.date(1980, 1, 1))
value = models.IntegerField(default=42)
callable_default = models.IntegerField(default=callable_default)
@@ -28,45 +28,48 @@ class Defaults(models.Model):
class ChoiceModel(models.Model):
"""For ModelChoiceField and ModelMultipleChoiceField tests."""
+
CHOICES = [
- ('', 'No Preference'),
- ('f', 'Foo'),
- ('b', 'Bar'),
+ ("", "No Preference"),
+ ("f", "Foo"),
+ ("b", "Bar"),
]
INTEGER_CHOICES = [
- (None, 'No Preference'),
- (1, 'Foo'),
- (2, 'Bar'),
+ (None, "No Preference"),
+ (1, "Foo"),
+ (2, "Bar"),
]
STRING_CHOICES_WITH_NONE = [
- (None, 'No Preference'),
- ('f', 'Foo'),
- ('b', 'Bar'),
+ (None, "No Preference"),
+ ("f", "Foo"),
+ ("b", "Bar"),
]
name = models.CharField(max_length=10)
choice = models.CharField(max_length=2, blank=True, choices=CHOICES)
choice_string_w_none = models.CharField(
- max_length=2, blank=True, null=True, choices=STRING_CHOICES_WITH_NONE)
+ max_length=2, blank=True, null=True, choices=STRING_CHOICES_WITH_NONE
+ )
choice_integer = models.IntegerField(choices=INTEGER_CHOICES, blank=True, null=True)
class ChoiceOptionModel(models.Model):
"""Destination for ChoiceFieldModel's ForeignKey.
Can't reuse ChoiceModel because error_message tests require that it have no instances."""
+
name = models.CharField(max_length=10)
class Meta:
- ordering = ('name',)
+ ordering = ("name",)
def __str__(self):
- return 'ChoiceOption %d' % self.pk
+ return "ChoiceOption %d" % self.pk
def choice_default():
- return ChoiceOptionModel.objects.get_or_create(name='default')[0].pk
+ return ChoiceOptionModel.objects.get_or_create(name="default")[0].pk
def choice_default_list():
@@ -84,6 +87,7 @@ def int_list_default():
class ChoiceFieldModel(models.Model):
"""Model with ForeignKey to another model, for testing ModelForm
generation with ModelChoiceField."""
+
choice = models.ForeignKey(
ChoiceOptionModel,
models.CASCADE,
@@ -94,19 +98,19 @@ class ChoiceFieldModel(models.Model):
ChoiceOptionModel,
models.CASCADE,
blank=False,
- related_name='choice_int',
+ related_name="choice_int",
default=int_default,
)
multi_choice = models.ManyToManyField(
ChoiceOptionModel,
blank=False,
- related_name='multi_choice',
+ related_name="multi_choice",
default=choice_default_list,
)
multi_choice_int = models.ManyToManyField(
ChoiceOptionModel,
blank=False,
- related_name='multi_choice_int',
+ related_name="multi_choice_int",
default=int_list_default,
)
@@ -115,18 +119,18 @@ class OptionalMultiChoiceModel(models.Model):
multi_choice = models.ManyToManyField(
ChoiceOptionModel,
blank=False,
- related_name='not_relevant',
+ related_name="not_relevant",
default=choice_default,
)
multi_choice_optional = models.ManyToManyField(
ChoiceOptionModel,
blank=True,
- related_name='not_relevant2',
+ related_name="not_relevant2",
)
class FileModel(models.Model):
- file = models.FileField(storage=temp_storage, upload_to='tests')
+ file = models.FileField(storage=temp_storage, upload_to="tests")
class Article(models.Model):
diff --git a/tests/forms_tests/tests/__init__.py b/tests/forms_tests/tests/__init__.py
index 3d1d8eefa4..193a7149a1 100644
--- a/tests/forms_tests/tests/__init__.py
+++ b/tests/forms_tests/tests/__init__.py
@@ -9,8 +9,8 @@ except ImportError:
def jinja2_tests(test_func):
- test_func = skipIf(jinja2 is None, 'this test requires jinja2')(test_func)
+ test_func = skipIf(jinja2 is None, "this test requires jinja2")(test_func)
return override_settings(
- FORM_RENDERER='django.forms.renderers.Jinja2',
- TEMPLATES={'BACKEND': 'django.template.backends.jinja2.Jinja2'},
+ FORM_RENDERER="django.forms.renderers.Jinja2",
+ TEMPLATES={"BACKEND": "django.template.backends.jinja2.Jinja2"},
)(test_func)
diff --git a/tests/forms_tests/tests/test_deprecation_forms.py b/tests/forms_tests/tests/test_deprecation_forms.py
index 6bdb595602..2a4fb6b0e1 100644
--- a/tests/forms_tests/tests/test_deprecation_forms.py
+++ b/tests/forms_tests/tests/test_deprecation_forms.py
@@ -13,8 +13,8 @@ class DivErrorList(ErrorList):
def as_divs(self):
if not self:
- return ''
- return '<div class="errorlist">%s</div>' % ''.join(
+ return ""
+ return '<div class="errorlist">%s</div>' % "".join(
f'<div class="error">{error}</div>' for error in self
)
@@ -22,16 +22,16 @@ class DivErrorList(ErrorList):
class DeprecationTests(SimpleTestCase):
def test_deprecation_warning_html_output(self):
msg = (
- 'django.forms.BaseForm._html_output() is deprecated. Please use '
- '.render() and .get_context() instead.'
+ "django.forms.BaseForm._html_output() is deprecated. Please use "
+ ".render() and .get_context() instead."
)
with self.assertRaisesMessage(RemovedInDjango50Warning, msg):
form = Person()
form._html_output(
normal_row='<p id="p_%(field_name)s"></p>',
- error_row='%s',
- row_ender='</p>',
- help_text_html=' %s',
+ error_row="%s",
+ row_ender="</p>",
+ help_text_html=" %s",
errors_on_separate_row=True,
)
@@ -40,11 +40,11 @@ class DeprecationTests(SimpleTestCase):
email = EmailField()
comment = CharField()
- data = {'email': 'invalid'}
+ data = {"email": "invalid"}
f = EmailForm(data, error_class=DivErrorList)
msg = (
- 'Returning a plain string from DivErrorList is deprecated. Please '
- 'customize via the template system instead.'
+ "Returning a plain string from DivErrorList is deprecated. Please "
+ "customize via the template system instead."
)
with self.assertRaisesMessage(RemovedInDjango50Warning, msg):
f.as_p()
@@ -58,7 +58,7 @@ class DeprecatedTests(SimpleTestCase):
email = EmailField()
comment = CharField()
- data = {'email': 'invalid'}
+ data = {"email": "invalid"}
f = CommentForm(data, auto_id=False, error_class=DivErrorList)
self.assertHTMLEqual(
f.as_p(),
@@ -73,15 +73,16 @@ class DeprecatedTests(SimpleTestCase):
def test_field_name(self):
"""#5749 - `field_name` may be used as a key in _html_output()."""
+
class SomeForm(Form):
some_field = CharField()
def as_p(self):
return self._html_output(
normal_row='<p id="p_%(field_name)s"></p>',
- error_row='%s',
- row_ender='</p>',
- help_text_html=' %s',
+ error_row="%s",
+ row_ender="</p>",
+ help_text_html=" %s",
errors_on_separate_row=True,
)
@@ -92,15 +93,16 @@ class DeprecatedTests(SimpleTestCase):
"""
`css_classes` may be used as a key in _html_output() (empty classes).
"""
+
class SomeForm(Form):
some_field = CharField()
def as_p(self):
return self._html_output(
normal_row='<p class="%(css_classes)s"></p>',
- error_row='%s',
- row_ender='</p>',
- help_text_html=' %s',
+ error_row="%s",
+ row_ender="</p>",
+ help_text_html=" %s",
errors_on_separate_row=True,
)
@@ -112,16 +114,17 @@ class DeprecatedTests(SimpleTestCase):
`css_classes` may be used as a key in _html_output() (class comes
from required_css_class in this case).
"""
+
class SomeForm(Form):
some_field = CharField()
- required_css_class = 'foo'
+ required_css_class = "foo"
def as_p(self):
return self._html_output(
normal_row='<p class="%(css_classes)s"></p>',
- error_row='%s',
- row_ender='</p>',
- help_text_html=' %s',
+ error_row="%s",
+ row_ender="</p>",
+ help_text_html=" %s",
errors_on_separate_row=True,
)
@@ -133,6 +136,7 @@ class DeprecatedTests(SimpleTestCase):
BaseForm._html_output() should merge all the hidden input fields and
put them in the last row.
"""
+
class SomeForm(Form):
hidden1 = CharField(widget=HiddenInput)
custom = CharField()
@@ -140,10 +144,10 @@ class DeprecatedTests(SimpleTestCase):
def as_p(self):
return self._html_output(
- normal_row='<p%(html_class_attr)s>%(field)s %(field_name)s</p>',
- error_row='%s',
- row_ender='</p>',
- help_text_html=' %s',
+ normal_row="<p%(html_class_attr)s>%(field)s %(field_name)s</p>",
+ error_row="%s",
+ row_ender="</p>",
+ help_text_html=" %s",
errors_on_separate_row=True,
)
@@ -152,7 +156,7 @@ class DeprecatedTests(SimpleTestCase):
form.as_p(),
'<p><input id="id_custom" name="custom" type="text" required> custom'
'<input id="id_hidden1" name="hidden1" type="hidden">'
- '<input id="id_hidden2" name="hidden2" type="hidden"></p>'
+ '<input id="id_hidden2" name="hidden2" type="hidden"></p>',
)
def test_field_name_with_hidden_input_and_non_matching_row_ender(self):
@@ -160,6 +164,7 @@ class DeprecatedTests(SimpleTestCase):
BaseForm._html_output() should merge all the hidden input fields and
put them in the last row ended with the specific row ender.
"""
+
class SomeForm(Form):
hidden1 = CharField(widget=HiddenInput)
custom = CharField()
@@ -167,10 +172,10 @@ class DeprecatedTests(SimpleTestCase):
def as_p(self):
return self._html_output(
- normal_row='<p%(html_class_attr)s>%(field)s %(field_name)s</p>',
- error_row='%s',
- row_ender='<hr><hr>',
- help_text_html=' %s',
+ normal_row="<p%(html_class_attr)s>%(field)s %(field_name)s</p>",
+ error_row="%s",
+ row_ender="<hr><hr>",
+ help_text_html=" %s",
errors_on_separate_row=True,
)
@@ -179,5 +184,5 @@ class DeprecatedTests(SimpleTestCase):
form.as_p(),
'<p><input id="id_custom" name="custom" type="text" required> custom</p>\n'
'<input id="id_hidden1" name="hidden1" type="hidden">'
- '<input id="id_hidden2" name="hidden2" type="hidden"><hr><hr>'
+ '<input id="id_hidden2" name="hidden2" type="hidden"><hr><hr>',
)
diff --git a/tests/forms_tests/tests/test_error_messages.py b/tests/forms_tests/tests/test_error_messages.py
index 340c39546c..2ad356858f 100644
--- a/tests/forms_tests/tests/test_error_messages.py
+++ b/tests/forms_tests/tests/test_error_messages.py
@@ -1,11 +1,26 @@
from django.core.exceptions import ValidationError
from django.core.files.uploadedfile import SimpleUploadedFile
from django.forms import (
- BooleanField, CharField, ChoiceField, DateField, DateTimeField,
- DecimalField, EmailField, FileField, FloatField, Form,
- GenericIPAddressField, IntegerField, ModelChoiceField,
- ModelMultipleChoiceField, MultipleChoiceField, RegexField,
- SplitDateTimeField, TimeField, URLField, utils,
+ BooleanField,
+ CharField,
+ ChoiceField,
+ DateField,
+ DateTimeField,
+ DecimalField,
+ EmailField,
+ FileField,
+ FloatField,
+ Form,
+ GenericIPAddressField,
+ IntegerField,
+ ModelChoiceField,
+ ModelMultipleChoiceField,
+ MultipleChoiceField,
+ RegexField,
+ SplitDateTimeField,
+ TimeField,
+ URLField,
+ utils,
)
from django.template import Context, Template
from django.test import SimpleTestCase, TestCase
@@ -24,188 +39,188 @@ class AssertFormErrorsMixin:
class FormsErrorMessagesTestCase(SimpleTestCase, AssertFormErrorsMixin):
def test_charfield(self):
e = {
- 'required': 'REQUIRED',
- 'min_length': 'LENGTH %(show_value)s, MIN LENGTH %(limit_value)s',
- 'max_length': 'LENGTH %(show_value)s, MAX LENGTH %(limit_value)s',
+ "required": "REQUIRED",
+ "min_length": "LENGTH %(show_value)s, MIN LENGTH %(limit_value)s",
+ "max_length": "LENGTH %(show_value)s, MAX LENGTH %(limit_value)s",
}
f = CharField(min_length=5, max_length=10, error_messages=e)
- self.assertFormErrors(['REQUIRED'], f.clean, '')
- self.assertFormErrors(['LENGTH 4, MIN LENGTH 5'], f.clean, '1234')
- self.assertFormErrors(['LENGTH 11, MAX LENGTH 10'], f.clean, '12345678901')
+ self.assertFormErrors(["REQUIRED"], f.clean, "")
+ self.assertFormErrors(["LENGTH 4, MIN LENGTH 5"], f.clean, "1234")
+ self.assertFormErrors(["LENGTH 11, MAX LENGTH 10"], f.clean, "12345678901")
def test_integerfield(self):
e = {
- 'required': 'REQUIRED',
- 'invalid': 'INVALID',
- 'min_value': 'MIN VALUE IS %(limit_value)s',
- 'max_value': 'MAX VALUE IS %(limit_value)s',
+ "required": "REQUIRED",
+ "invalid": "INVALID",
+ "min_value": "MIN VALUE IS %(limit_value)s",
+ "max_value": "MAX VALUE IS %(limit_value)s",
}
f = IntegerField(min_value=5, max_value=10, error_messages=e)
- self.assertFormErrors(['REQUIRED'], f.clean, '')
- self.assertFormErrors(['INVALID'], f.clean, 'abc')
- self.assertFormErrors(['MIN VALUE IS 5'], f.clean, '4')
- self.assertFormErrors(['MAX VALUE IS 10'], f.clean, '11')
+ self.assertFormErrors(["REQUIRED"], f.clean, "")
+ self.assertFormErrors(["INVALID"], f.clean, "abc")
+ self.assertFormErrors(["MIN VALUE IS 5"], f.clean, "4")
+ self.assertFormErrors(["MAX VALUE IS 10"], f.clean, "11")
def test_floatfield(self):
e = {
- 'required': 'REQUIRED',
- 'invalid': 'INVALID',
- 'min_value': 'MIN VALUE IS %(limit_value)s',
- 'max_value': 'MAX VALUE IS %(limit_value)s',
+ "required": "REQUIRED",
+ "invalid": "INVALID",
+ "min_value": "MIN VALUE IS %(limit_value)s",
+ "max_value": "MAX VALUE IS %(limit_value)s",
}
f = FloatField(min_value=5, max_value=10, error_messages=e)
- self.assertFormErrors(['REQUIRED'], f.clean, '')
- self.assertFormErrors(['INVALID'], f.clean, 'abc')
- self.assertFormErrors(['MIN VALUE IS 5'], f.clean, '4')
- self.assertFormErrors(['MAX VALUE IS 10'], f.clean, '11')
+ self.assertFormErrors(["REQUIRED"], f.clean, "")
+ self.assertFormErrors(["INVALID"], f.clean, "abc")
+ self.assertFormErrors(["MIN VALUE IS 5"], f.clean, "4")
+ self.assertFormErrors(["MAX VALUE IS 10"], f.clean, "11")
def test_decimalfield(self):
e = {
- 'required': 'REQUIRED',
- 'invalid': 'INVALID',
- 'min_value': 'MIN VALUE IS %(limit_value)s',
- 'max_value': 'MAX VALUE IS %(limit_value)s',
- 'max_digits': 'MAX DIGITS IS %(max)s',
- 'max_decimal_places': 'MAX DP IS %(max)s',
- 'max_whole_digits': 'MAX DIGITS BEFORE DP IS %(max)s',
+ "required": "REQUIRED",
+ "invalid": "INVALID",
+ "min_value": "MIN VALUE IS %(limit_value)s",
+ "max_value": "MAX VALUE IS %(limit_value)s",
+ "max_digits": "MAX DIGITS IS %(max)s",
+ "max_decimal_places": "MAX DP IS %(max)s",
+ "max_whole_digits": "MAX DIGITS BEFORE DP IS %(max)s",
}
f = DecimalField(min_value=5, max_value=10, error_messages=e)
- self.assertFormErrors(['REQUIRED'], f.clean, '')
- self.assertFormErrors(['INVALID'], f.clean, 'abc')
- self.assertFormErrors(['MIN VALUE IS 5'], f.clean, '4')
- self.assertFormErrors(['MAX VALUE IS 10'], f.clean, '11')
+ self.assertFormErrors(["REQUIRED"], f.clean, "")
+ self.assertFormErrors(["INVALID"], f.clean, "abc")
+ self.assertFormErrors(["MIN VALUE IS 5"], f.clean, "4")
+ self.assertFormErrors(["MAX VALUE IS 10"], f.clean, "11")
f2 = DecimalField(max_digits=4, decimal_places=2, error_messages=e)
- self.assertFormErrors(['MAX DIGITS IS 4'], f2.clean, '123.45')
- self.assertFormErrors(['MAX DP IS 2'], f2.clean, '1.234')
- self.assertFormErrors(['MAX DIGITS BEFORE DP IS 2'], f2.clean, '123.4')
+ self.assertFormErrors(["MAX DIGITS IS 4"], f2.clean, "123.45")
+ self.assertFormErrors(["MAX DP IS 2"], f2.clean, "1.234")
+ self.assertFormErrors(["MAX DIGITS BEFORE DP IS 2"], f2.clean, "123.4")
def test_datefield(self):
e = {
- 'required': 'REQUIRED',
- 'invalid': 'INVALID',
+ "required": "REQUIRED",
+ "invalid": "INVALID",
}
f = DateField(error_messages=e)
- self.assertFormErrors(['REQUIRED'], f.clean, '')
- self.assertFormErrors(['INVALID'], f.clean, 'abc')
+ self.assertFormErrors(["REQUIRED"], f.clean, "")
+ self.assertFormErrors(["INVALID"], f.clean, "abc")
def test_timefield(self):
e = {
- 'required': 'REQUIRED',
- 'invalid': 'INVALID',
+ "required": "REQUIRED",
+ "invalid": "INVALID",
}
f = TimeField(error_messages=e)
- self.assertFormErrors(['REQUIRED'], f.clean, '')
- self.assertFormErrors(['INVALID'], f.clean, 'abc')
+ self.assertFormErrors(["REQUIRED"], f.clean, "")
+ self.assertFormErrors(["INVALID"], f.clean, "abc")
def test_datetimefield(self):
e = {
- 'required': 'REQUIRED',
- 'invalid': 'INVALID',
+ "required": "REQUIRED",
+ "invalid": "INVALID",
}
f = DateTimeField(error_messages=e)
- self.assertFormErrors(['REQUIRED'], f.clean, '')
- self.assertFormErrors(['INVALID'], f.clean, 'abc')
+ self.assertFormErrors(["REQUIRED"], f.clean, "")
+ self.assertFormErrors(["INVALID"], f.clean, "abc")
def test_regexfield(self):
e = {
- 'required': 'REQUIRED',
- 'invalid': 'INVALID',
- 'min_length': 'LENGTH %(show_value)s, MIN LENGTH %(limit_value)s',
- 'max_length': 'LENGTH %(show_value)s, MAX LENGTH %(limit_value)s',
+ "required": "REQUIRED",
+ "invalid": "INVALID",
+ "min_length": "LENGTH %(show_value)s, MIN LENGTH %(limit_value)s",
+ "max_length": "LENGTH %(show_value)s, MAX LENGTH %(limit_value)s",
}
- f = RegexField(r'^[0-9]+$', min_length=5, max_length=10, error_messages=e)
- self.assertFormErrors(['REQUIRED'], f.clean, '')
- self.assertFormErrors(['INVALID'], f.clean, 'abcde')
- self.assertFormErrors(['LENGTH 4, MIN LENGTH 5'], f.clean, '1234')
- self.assertFormErrors(['LENGTH 11, MAX LENGTH 10'], f.clean, '12345678901')
+ f = RegexField(r"^[0-9]+$", min_length=5, max_length=10, error_messages=e)
+ self.assertFormErrors(["REQUIRED"], f.clean, "")
+ self.assertFormErrors(["INVALID"], f.clean, "abcde")
+ self.assertFormErrors(["LENGTH 4, MIN LENGTH 5"], f.clean, "1234")
+ self.assertFormErrors(["LENGTH 11, MAX LENGTH 10"], f.clean, "12345678901")
def test_emailfield(self):
e = {
- 'required': 'REQUIRED',
- 'invalid': 'INVALID',
- 'min_length': 'LENGTH %(show_value)s, MIN LENGTH %(limit_value)s',
- 'max_length': 'LENGTH %(show_value)s, MAX LENGTH %(limit_value)s',
+ "required": "REQUIRED",
+ "invalid": "INVALID",
+ "min_length": "LENGTH %(show_value)s, MIN LENGTH %(limit_value)s",
+ "max_length": "LENGTH %(show_value)s, MAX LENGTH %(limit_value)s",
}
f = EmailField(min_length=8, max_length=10, error_messages=e)
- self.assertFormErrors(['REQUIRED'], f.clean, '')
- self.assertFormErrors(['INVALID'], f.clean, 'abcdefgh')
- self.assertFormErrors(['LENGTH 7, MIN LENGTH 8'], f.clean, 'a@b.com')
- self.assertFormErrors(['LENGTH 11, MAX LENGTH 10'], f.clean, 'aye@bee.com')
+ self.assertFormErrors(["REQUIRED"], f.clean, "")
+ self.assertFormErrors(["INVALID"], f.clean, "abcdefgh")
+ self.assertFormErrors(["LENGTH 7, MIN LENGTH 8"], f.clean, "a@b.com")
+ self.assertFormErrors(["LENGTH 11, MAX LENGTH 10"], f.clean, "aye@bee.com")
def test_filefield(self):
e = {
- 'required': 'REQUIRED',
- 'invalid': 'INVALID',
- 'missing': 'MISSING',
- 'empty': 'EMPTY FILE',
+ "required": "REQUIRED",
+ "invalid": "INVALID",
+ "missing": "MISSING",
+ "empty": "EMPTY FILE",
}
f = FileField(error_messages=e)
- self.assertFormErrors(['REQUIRED'], f.clean, '')
- self.assertFormErrors(['INVALID'], f.clean, 'abc')
- self.assertFormErrors(['EMPTY FILE'], f.clean, SimpleUploadedFile('name', None))
- self.assertFormErrors(['EMPTY FILE'], f.clean, SimpleUploadedFile('name', ''))
+ self.assertFormErrors(["REQUIRED"], f.clean, "")
+ self.assertFormErrors(["INVALID"], f.clean, "abc")
+ self.assertFormErrors(["EMPTY FILE"], f.clean, SimpleUploadedFile("name", None))
+ self.assertFormErrors(["EMPTY FILE"], f.clean, SimpleUploadedFile("name", ""))
def test_urlfield(self):
e = {
- 'required': 'REQUIRED',
- 'invalid': 'INVALID',
- 'max_length': '"%(value)s" has more than %(limit_value)d characters.',
+ "required": "REQUIRED",
+ "invalid": "INVALID",
+ "max_length": '"%(value)s" has more than %(limit_value)d characters.',
}
f = URLField(error_messages=e, max_length=17)
- self.assertFormErrors(['REQUIRED'], f.clean, '')
- self.assertFormErrors(['INVALID'], f.clean, 'abc.c')
+ self.assertFormErrors(["REQUIRED"], f.clean, "")
+ self.assertFormErrors(["INVALID"], f.clean, "abc.c")
self.assertFormErrors(
['"http://djangoproject.com" has more than 17 characters.'],
f.clean,
- 'djangoproject.com'
+ "djangoproject.com",
)
def test_booleanfield(self):
e = {
- 'required': 'REQUIRED',
+ "required": "REQUIRED",
}
f = BooleanField(error_messages=e)
- self.assertFormErrors(['REQUIRED'], f.clean, '')
+ self.assertFormErrors(["REQUIRED"], f.clean, "")
def test_choicefield(self):
e = {
- 'required': 'REQUIRED',
- 'invalid_choice': '%(value)s IS INVALID CHOICE',
+ "required": "REQUIRED",
+ "invalid_choice": "%(value)s IS INVALID CHOICE",
}
- f = ChoiceField(choices=[('a', 'aye')], error_messages=e)
- self.assertFormErrors(['REQUIRED'], f.clean, '')
- self.assertFormErrors(['b IS INVALID CHOICE'], f.clean, 'b')
+ f = ChoiceField(choices=[("a", "aye")], error_messages=e)
+ self.assertFormErrors(["REQUIRED"], f.clean, "")
+ self.assertFormErrors(["b IS INVALID CHOICE"], f.clean, "b")
def test_multiplechoicefield(self):
e = {
- 'required': 'REQUIRED',
- 'invalid_choice': '%(value)s IS INVALID CHOICE',
- 'invalid_list': 'NOT A LIST',
+ "required": "REQUIRED",
+ "invalid_choice": "%(value)s IS INVALID CHOICE",
+ "invalid_list": "NOT A LIST",
}
- f = MultipleChoiceField(choices=[('a', 'aye')], error_messages=e)
- self.assertFormErrors(['REQUIRED'], f.clean, '')
- self.assertFormErrors(['NOT A LIST'], f.clean, 'b')
- self.assertFormErrors(['b IS INVALID CHOICE'], f.clean, ['b'])
+ f = MultipleChoiceField(choices=[("a", "aye")], error_messages=e)
+ self.assertFormErrors(["REQUIRED"], f.clean, "")
+ self.assertFormErrors(["NOT A LIST"], f.clean, "b")
+ self.assertFormErrors(["b IS INVALID CHOICE"], f.clean, ["b"])
def test_splitdatetimefield(self):
e = {
- 'required': 'REQUIRED',
- 'invalid_date': 'INVALID DATE',
- 'invalid_time': 'INVALID TIME',
+ "required": "REQUIRED",
+ "invalid_date": "INVALID DATE",
+ "invalid_time": "INVALID TIME",
}
f = SplitDateTimeField(error_messages=e)
- self.assertFormErrors(['REQUIRED'], f.clean, '')
- self.assertFormErrors(['INVALID DATE', 'INVALID TIME'], f.clean, ['a', 'b'])
+ self.assertFormErrors(["REQUIRED"], f.clean, "")
+ self.assertFormErrors(["INVALID DATE", "INVALID TIME"], f.clean, ["a", "b"])
def test_generic_ipaddressfield(self):
e = {
- 'required': 'REQUIRED',
- 'invalid': 'INVALID IP ADDRESS',
+ "required": "REQUIRED",
+ "invalid": "INVALID IP ADDRESS",
}
f = GenericIPAddressField(error_messages=e)
- self.assertFormErrors(['REQUIRED'], f.clean, '')
- self.assertFormErrors(['INVALID IP ADDRESS'], f.clean, '127.0.0')
+ self.assertFormErrors(["REQUIRED"], f.clean, "")
+ self.assertFormErrors(["INVALID IP ADDRESS"], f.clean, "127.0.0")
def test_subclassing_errorlist(self):
class TestForm(Form):
@@ -222,102 +237,113 @@ class FormsErrorMessagesTestCase(SimpleTestCase, AssertFormErrorsMixin):
def as_divs(self):
if not self:
- return ''
- return mark_safe('<div class="error">%s</div>' % ''.join('<p>%s</p>' % e for e in self))
+ return ""
+ return mark_safe(
+ '<div class="error">%s</div>'
+ % "".join("<p>%s</p>" % e for e in self)
+ )
# This form should print errors the default way.
- form1 = TestForm({'first_name': 'John'})
+ form1 = TestForm({"first_name": "John"})
self.assertHTMLEqual(
- str(form1['last_name'].errors),
- '<ul class="errorlist"><li>This field is required.</li></ul>'
+ str(form1["last_name"].errors),
+ '<ul class="errorlist"><li>This field is required.</li></ul>',
)
self.assertHTMLEqual(
- str(form1.errors['__all__']),
- '<ul class="errorlist nonfield"><li>I like to be awkward.</li></ul>'
+ str(form1.errors["__all__"]),
+ '<ul class="errorlist nonfield"><li>I like to be awkward.</li></ul>',
)
# This one should wrap error groups in the customized way.
- form2 = TestForm({'first_name': 'John'}, error_class=CustomErrorList)
- self.assertHTMLEqual(str(form2['last_name'].errors), '<div class="error"><p>This field is required.</p></div>')
- self.assertHTMLEqual(str(form2.errors['__all__']), '<div class="error"><p>I like to be awkward.</p></div>')
+ form2 = TestForm({"first_name": "John"}, error_class=CustomErrorList)
+ self.assertHTMLEqual(
+ str(form2["last_name"].errors),
+ '<div class="error"><p>This field is required.</p></div>',
+ )
+ self.assertHTMLEqual(
+ str(form2.errors["__all__"]),
+ '<div class="error"><p>I like to be awkward.</p></div>',
+ )
def test_error_messages_escaping(self):
# The forms layer doesn't escape input values directly because error
# messages might be presented in non-HTML contexts. Instead, the
# message is marked for escaping by the template engine, so a template
# is needed to trigger the escaping.
- t = Template('{{ form.errors }}')
+ t = Template("{{ form.errors }}")
class SomeForm(Form):
- field = ChoiceField(choices=[('one', 'One')])
+ field = ChoiceField(choices=[("one", "One")])
- f = SomeForm({'field': '<script>'})
+ f = SomeForm({"field": "<script>"})
self.assertHTMLEqual(
- t.render(Context({'form': f})),
+ t.render(Context({"form": f})),
'<ul class="errorlist"><li>field<ul class="errorlist">'
- '<li>Select a valid choice. &lt;script&gt; is not one of the '
- 'available choices.</li></ul></li></ul>'
+ "<li>Select a valid choice. &lt;script&gt; is not one of the "
+ "available choices.</li></ul></li></ul>",
)
class SomeForm(Form):
- field = MultipleChoiceField(choices=[('one', 'One')])
+ field = MultipleChoiceField(choices=[("one", "One")])
- f = SomeForm({'field': ['<script>']})
+ f = SomeForm({"field": ["<script>"]})
self.assertHTMLEqual(
- t.render(Context({'form': f})),
+ t.render(Context({"form": f})),
'<ul class="errorlist"><li>field<ul class="errorlist">'
- '<li>Select a valid choice. &lt;script&gt; is not one of the '
- 'available choices.</li></ul></li></ul>'
+ "<li>Select a valid choice. &lt;script&gt; is not one of the "
+ "available choices.</li></ul></li></ul>",
)
class SomeForm(Form):
field = ModelMultipleChoiceField(ChoiceModel.objects.all())
- f = SomeForm({'field': ['<script>']})
+ f = SomeForm({"field": ["<script>"]})
self.assertHTMLEqual(
- t.render(Context({'form': f})),
+ t.render(Context({"form": f})),
'<ul class="errorlist"><li>field<ul class="errorlist">'
- '<li>“&lt;script&gt;” is not a valid value.</li>'
- '</ul></li></ul>'
+ "<li>“&lt;script&gt;” is not a valid value.</li>"
+ "</ul></li></ul>",
)
class ModelChoiceFieldErrorMessagesTestCase(TestCase, AssertFormErrorsMixin):
def test_modelchoicefield(self):
# Create choices for the model choice field tests below.
- ChoiceModel.objects.create(pk=1, name='a')
- ChoiceModel.objects.create(pk=2, name='b')
- ChoiceModel.objects.create(pk=3, name='c')
+ ChoiceModel.objects.create(pk=1, name="a")
+ ChoiceModel.objects.create(pk=2, name="b")
+ ChoiceModel.objects.create(pk=3, name="c")
# ModelChoiceField
e = {
- 'required': 'REQUIRED',
- 'invalid_choice': 'INVALID CHOICE',
+ "required": "REQUIRED",
+ "invalid_choice": "INVALID CHOICE",
}
f = ModelChoiceField(queryset=ChoiceModel.objects.all(), error_messages=e)
- self.assertFormErrors(['REQUIRED'], f.clean, '')
- self.assertFormErrors(['INVALID CHOICE'], f.clean, '4')
+ self.assertFormErrors(["REQUIRED"], f.clean, "")
+ self.assertFormErrors(["INVALID CHOICE"], f.clean, "4")
# ModelMultipleChoiceField
e = {
- 'required': 'REQUIRED',
- 'invalid_choice': '%(value)s IS INVALID CHOICE',
- 'invalid_list': 'NOT A LIST OF VALUES',
+ "required": "REQUIRED",
+ "invalid_choice": "%(value)s IS INVALID CHOICE",
+ "invalid_list": "NOT A LIST OF VALUES",
}
- f = ModelMultipleChoiceField(queryset=ChoiceModel.objects.all(), error_messages=e)
- self.assertFormErrors(['REQUIRED'], f.clean, '')
- self.assertFormErrors(['NOT A LIST OF VALUES'], f.clean, '3')
- self.assertFormErrors(['4 IS INVALID CHOICE'], f.clean, ['4'])
+ f = ModelMultipleChoiceField(
+ queryset=ChoiceModel.objects.all(), error_messages=e
+ )
+ self.assertFormErrors(["REQUIRED"], f.clean, "")
+ self.assertFormErrors(["NOT A LIST OF VALUES"], f.clean, "3")
+ self.assertFormErrors(["4 IS INVALID CHOICE"], f.clean, ["4"])
def test_modelchoicefield_value_placeholder(self):
f = ModelChoiceField(
queryset=ChoiceModel.objects.all(),
error_messages={
- 'invalid_choice': '"%(value)s" is not one of the available choices.',
+ "invalid_choice": '"%(value)s" is not one of the available choices.',
},
)
self.assertFormErrors(
['"invalid" is not one of the available choices.'],
f.clean,
- 'invalid',
+ "invalid",
)
diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py
index aa47481998..5467cee9ad 100644
--- a/tests/forms_tests/tests/test_forms.py
+++ b/tests/forms_tests/tests/test_forms.py
@@ -7,12 +7,34 @@ from django.core.exceptions import NON_FIELD_ERRORS
from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.validators import MaxValueValidator, RegexValidator
from django.forms import (
- BooleanField, CharField, CheckboxSelectMultiple, ChoiceField, DateField,
- DateTimeField, EmailField, FileField, FileInput, FloatField, Form,
- HiddenInput, ImageField, IntegerField, MultipleChoiceField,
- MultipleHiddenInput, MultiValueField, MultiWidget, NullBooleanField,
- PasswordInput, RadioSelect, Select, SplitDateTimeField,
- SplitHiddenDateTimeWidget, Textarea, TextInput, TimeField, ValidationError,
+ BooleanField,
+ CharField,
+ CheckboxSelectMultiple,
+ ChoiceField,
+ DateField,
+ DateTimeField,
+ EmailField,
+ FileField,
+ FileInput,
+ FloatField,
+ Form,
+ HiddenInput,
+ ImageField,
+ IntegerField,
+ MultipleChoiceField,
+ MultipleHiddenInput,
+ MultiValueField,
+ MultiWidget,
+ NullBooleanField,
+ PasswordInput,
+ RadioSelect,
+ Select,
+ SplitDateTimeField,
+ SplitHiddenDateTimeWidget,
+ Textarea,
+ TextInput,
+ TimeField,
+ ValidationError,
forms,
)
from django.forms.renderers import DjangoTemplates, get_default_renderer
@@ -29,7 +51,7 @@ from . import jinja2_tests
class FrameworkForm(Form):
name = CharField()
- language = ChoiceField(choices=[('P', 'Python'), ('J', 'Java')], widget=RadioSelect)
+ language = ChoiceField(choices=[("P", "Python"), ("J", "Java")], widget=RadioSelect)
class Person(Form):
@@ -39,7 +61,7 @@ class Person(Form):
class PersonNew(Form):
- first_name = CharField(widget=TextInput(attrs={'id': 'first_name_id'}))
+ first_name = CharField(widget=TextInput(attrs={"id": "first_name_id"}))
last_name = CharField()
birthday = DateField()
@@ -47,7 +69,7 @@ class PersonNew(Form):
class SongForm(Form):
name = CharField()
composers = MultipleChoiceField(
- choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')],
+ choices=[("J", "John Lennon"), ("P", "Paul McCartney")],
widget=CheckboxSelectMultiple,
)
@@ -64,33 +86,35 @@ class FormsTestCase(SimpleTestCase):
def test_form(self):
# Pass a dictionary to a Form's __init__().
- p = Person({'first_name': 'John', 'last_name': 'Lennon', 'birthday': '1940-10-9'})
+ p = Person(
+ {"first_name": "John", "last_name": "Lennon", "birthday": "1940-10-9"}
+ )
self.assertTrue(p.is_bound)
self.assertEqual(p.errors, {})
self.assertIsInstance(p.errors, dict)
self.assertTrue(p.is_valid())
- self.assertHTMLEqual(p.errors.as_ul(), '')
- self.assertEqual(p.errors.as_text(), '')
- self.assertEqual(p.cleaned_data["first_name"], 'John')
- self.assertEqual(p.cleaned_data["last_name"], 'Lennon')
+ self.assertHTMLEqual(p.errors.as_ul(), "")
+ self.assertEqual(p.errors.as_text(), "")
+ self.assertEqual(p.cleaned_data["first_name"], "John")
+ self.assertEqual(p.cleaned_data["last_name"], "Lennon")
self.assertEqual(p.cleaned_data["birthday"], datetime.date(1940, 10, 9))
self.assertHTMLEqual(
- str(p['first_name']),
- '<input type="text" name="first_name" value="John" id="id_first_name" required>'
+ str(p["first_name"]),
+ '<input type="text" name="first_name" value="John" id="id_first_name" required>',
)
self.assertHTMLEqual(
- str(p['last_name']),
- '<input type="text" name="last_name" value="Lennon" id="id_last_name" required>'
+ str(p["last_name"]),
+ '<input type="text" name="last_name" value="Lennon" id="id_last_name" required>',
)
self.assertHTMLEqual(
- str(p['birthday']),
- '<input type="text" name="birthday" value="1940-10-9" id="id_birthday" required>'
+ str(p["birthday"]),
+ '<input type="text" name="birthday" value="1940-10-9" id="id_birthday" required>',
)
msg = "Key 'nonexistentfield' not found in 'Person'. Choices are: birthday, first_name, last_name."
with self.assertRaisesMessage(KeyError, msg):
- p['nonexistentfield']
+ p["nonexistentfield"]
form_output = []
@@ -98,10 +122,10 @@ class FormsTestCase(SimpleTestCase):
form_output.append(str(boundfield))
self.assertHTMLEqual(
- '\n'.join(form_output),
+ "\n".join(form_output),
"""<input type="text" name="first_name" value="John" id="id_first_name" required>
<input type="text" name="last_name" value="Lennon" id="id_last_name" required>
-<input type="text" name="birthday" value="1940-10-9" id="id_birthday" required>"""
+<input type="text" name="birthday" value="1940-10-9" id="id_birthday" required>""",
)
form_output = []
@@ -109,11 +133,14 @@ class FormsTestCase(SimpleTestCase):
for boundfield in p:
form_output.append([boundfield.label, boundfield.data])
- self.assertEqual(form_output, [
- ['First name', 'John'],
- ['Last name', 'Lennon'],
- ['Birthday', '1940-10-9']
- ])
+ self.assertEqual(
+ form_output,
+ [
+ ["First name", "John"],
+ ["Last name", "Lennon"],
+ ["Birthday", "1940-10-9"],
+ ],
+ )
self.assertHTMLEqual(
str(p),
"""<tr><th><label for="id_first_name">First name:</label></th><td>
@@ -121,16 +148,16 @@ class FormsTestCase(SimpleTestCase):
<tr><th><label for="id_last_name">Last name:</label></th><td>
<input type="text" name="last_name" value="Lennon" id="id_last_name" required></td></tr>
<tr><th><label for="id_birthday">Birthday:</label></th><td>
-<input type="text" name="birthday" value="1940-10-9" id="id_birthday" required></td></tr>"""
+<input type="text" name="birthday" value="1940-10-9" id="id_birthday" required></td></tr>""",
)
def test_empty_dict(self):
# Empty dictionaries are valid, too.
p = Person({})
self.assertTrue(p.is_bound)
- self.assertEqual(p.errors['first_name'], ['This field is required.'])
- self.assertEqual(p.errors['last_name'], ['This field is required.'])
- self.assertEqual(p.errors['birthday'], ['This field is required.'])
+ self.assertEqual(p.errors["first_name"], ["This field is required."])
+ self.assertEqual(p.errors["last_name"], ["This field is required."])
+ self.assertEqual(p.errors["birthday"], ["This field is required."])
self.assertFalse(p.is_valid())
self.assertEqual(p.cleaned_data, {})
self.assertHTMLEqual(
@@ -143,7 +170,7 @@ class FormsTestCase(SimpleTestCase):
<input type="text" name="last_name" id="id_last_name" required></td></tr>
<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" required></td></tr>"""
+<input type="text" name="birthday" id="id_birthday" required></td></tr>""",
)
self.assertHTMLEqual(
p.as_table(),
@@ -155,7 +182,7 @@ class FormsTestCase(SimpleTestCase):
<input type="text" name="last_name" id="id_last_name" required></td></tr>
<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" required></td></tr>"""
+<input type="text" name="birthday" id="id_birthday" required></td></tr>""",
)
self.assertHTMLEqual(
p.as_ul(),
@@ -167,7 +194,7 @@ class FormsTestCase(SimpleTestCase):
<input type="text" name="last_name" id="id_last_name" required></li>
<li><ul class="errorlist"><li>This field is required.</li></ul>
<label for="id_birthday">Birthday:</label>
-<input type="text" name="birthday" id="id_birthday" required></li>"""
+<input type="text" name="birthday" id="id_birthday" required></li>""",
)
self.assertHTMLEqual(
p.as_p(),
@@ -179,7 +206,7 @@ class FormsTestCase(SimpleTestCase):
<input type="text" name="last_name" id="id_last_name" required></p>
<ul class="errorlist"><li>This field is required.</li></ul>
<p><label for="id_birthday">Birthday:</label>
-<input type="text" name="birthday" id="id_birthday" required></p>"""
+<input type="text" name="birthday" id="id_birthday" required></p>""",
)
def test_empty_querydict_args(self):
@@ -207,7 +234,7 @@ class FormsTestCase(SimpleTestCase):
<tr><th><label for="id_last_name">Last name:</label></th><td>
<input type="text" name="last_name" id="id_last_name" required></td></tr>
<tr><th><label for="id_birthday">Birthday:</label></th><td>
-<input type="text" name="birthday" id="id_birthday" required></td></tr>"""
+<input type="text" name="birthday" id="id_birthday" required></td></tr>""",
)
self.assertHTMLEqual(
p.as_table(),
@@ -216,7 +243,7 @@ class FormsTestCase(SimpleTestCase):
<tr><th><label for="id_last_name">Last name:</label></th><td>
<input type="text" name="last_name" id="id_last_name" required></td></tr>
<tr><th><label for="id_birthday">Birthday:</label></th><td>
-<input type="text" name="birthday" id="id_birthday" required></td></tr>"""
+<input type="text" name="birthday" id="id_birthday" required></td></tr>""",
)
self.assertHTMLEqual(
p.as_ul(),
@@ -225,7 +252,7 @@ class FormsTestCase(SimpleTestCase):
<li><label for="id_last_name">Last name:</label>
<input type="text" name="last_name" id="id_last_name" required></li>
<li><label for="id_birthday">Birthday:</label>
-<input type="text" name="birthday" id="id_birthday" required></li>"""
+<input type="text" name="birthday" id="id_birthday" required></li>""",
)
self.assertHTMLEqual(
p.as_p(),
@@ -234,16 +261,18 @@ class FormsTestCase(SimpleTestCase):
<p><label for="id_last_name">Last name:</label>
<input type="text" name="last_name" id="id_last_name" required></p>
<p><label for="id_birthday">Birthday:</label>
-<input type="text" name="birthday" id="id_birthday" required></p>"""
+<input type="text" name="birthday" id="id_birthday" required></p>""",
)
def test_unicode_values(self):
# Unicode values are handled properly.
- p = Person({
- 'first_name': 'John',
- 'last_name': '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111',
- 'birthday': '1940-10-9'
- })
+ p = Person(
+ {
+ "first_name": "John",
+ "last_name": "\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111",
+ "birthday": "1940-10-9",
+ }
+ )
self.assertHTMLEqual(
p.as_table(),
'<tr><th><label for="id_first_name">First name:</label></th><td>'
@@ -253,7 +282,7 @@ class FormsTestCase(SimpleTestCase):
'value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111"'
'id="id_last_name" required></td></tr>\n'
'<tr><th><label for="id_birthday">Birthday:</label></th><td>'
- '<input type="text" name="birthday" value="1940-10-9" id="id_birthday" required></td></tr>'
+ '<input type="text" name="birthday" value="1940-10-9" id="id_birthday" required></td></tr>',
)
self.assertHTMLEqual(
p.as_ul(),
@@ -263,7 +292,7 @@ class FormsTestCase(SimpleTestCase):
'<input type="text" name="last_name" '
'value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" required></li>\n'
'<li><label for="id_birthday">Birthday:</label> '
- '<input type="text" name="birthday" value="1940-10-9" id="id_birthday" required></li>'
+ '<input type="text" name="birthday" value="1940-10-9" id="id_birthday" required></li>',
)
self.assertHTMLEqual(
p.as_p(),
@@ -273,32 +302,41 @@ class FormsTestCase(SimpleTestCase):
'<input type="text" name="last_name" '
'value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" required></p>\n'
'<p><label for="id_birthday">Birthday:</label> '
- '<input type="text" name="birthday" value="1940-10-9" id="id_birthday" required></p>'
+ '<input type="text" name="birthday" value="1940-10-9" id="id_birthday" required></p>',
)
- p = Person({'last_name': 'Lennon'})
- self.assertEqual(p.errors['first_name'], ['This field is required.'])
- self.assertEqual(p.errors['birthday'], ['This field is required.'])
+ p = Person({"last_name": "Lennon"})
+ self.assertEqual(p.errors["first_name"], ["This field is required."])
+ self.assertEqual(p.errors["birthday"], ["This field is required."])
self.assertFalse(p.is_valid())
self.assertEqual(
p.errors,
- {'birthday': ['This field is required.'], 'first_name': ['This field is required.']}
+ {
+ "birthday": ["This field is required."],
+ "first_name": ["This field is required."],
+ },
)
- self.assertEqual(p.cleaned_data, {'last_name': 'Lennon'})
- self.assertEqual(p['first_name'].errors, ['This field is required.'])
+ self.assertEqual(p.cleaned_data, {"last_name": "Lennon"})
+ self.assertEqual(p["first_name"].errors, ["This field is required."])
self.assertHTMLEqual(
- p['first_name'].errors.as_ul(),
- '<ul class="errorlist"><li>This field is required.</li></ul>'
+ p["first_name"].errors.as_ul(),
+ '<ul class="errorlist"><li>This field is required.</li></ul>',
)
- self.assertEqual(p['first_name'].errors.as_text(), '* This field is required.')
+ self.assertEqual(p["first_name"].errors.as_text(), "* This field is required.")
p = Person()
self.assertHTMLEqual(
- str(p['first_name']),
+ str(p["first_name"]),
'<input type="text" name="first_name" id="id_first_name" required>',
)
- self.assertHTMLEqual(str(p['last_name']), '<input type="text" name="last_name" id="id_last_name" required>')
- self.assertHTMLEqual(str(p['birthday']), '<input type="text" name="birthday" id="id_birthday" required>')
+ self.assertHTMLEqual(
+ str(p["last_name"]),
+ '<input type="text" name="last_name" id="id_last_name" required>',
+ )
+ self.assertHTMLEqual(
+ str(p["birthday"]),
+ '<input type="text" name="birthday" id="id_birthday" required>',
+ )
def test_cleaned_data_only_fields(self):
# cleaned_data will always *only* contain a key for fields defined in the
@@ -306,17 +344,17 @@ class FormsTestCase(SimpleTestCase):
# example, we pass a bunch of extra fields to the form constructor,
# but cleaned_data contains only the form's fields.
data = {
- 'first_name': 'John',
- 'last_name': 'Lennon',
- 'birthday': '1940-10-9',
- 'extra1': 'hello',
- 'extra2': 'hello',
+ "first_name": "John",
+ "last_name": "Lennon",
+ "birthday": "1940-10-9",
+ "extra1": "hello",
+ "extra2": "hello",
}
p = Person(data)
self.assertTrue(p.is_valid())
- self.assertEqual(p.cleaned_data['first_name'], 'John')
- self.assertEqual(p.cleaned_data['last_name'], 'Lennon')
- self.assertEqual(p.cleaned_data['birthday'], datetime.date(1940, 10, 9))
+ self.assertEqual(p.cleaned_data["first_name"], "John")
+ self.assertEqual(p.cleaned_data["last_name"], "Lennon")
+ self.assertEqual(p.cleaned_data["birthday"], datetime.date(1940, 10, 9))
def test_optional_data(self):
# cleaned_data will include a key and value for *all* fields defined in the Form,
@@ -329,12 +367,12 @@ class FormsTestCase(SimpleTestCase):
last_name = CharField()
nick_name = CharField(required=False)
- data = {'first_name': 'John', 'last_name': 'Lennon'}
+ data = {"first_name": "John", "last_name": "Lennon"}
f = OptionalPersonForm(data)
self.assertTrue(f.is_valid())
- self.assertEqual(f.cleaned_data['nick_name'], '')
- self.assertEqual(f.cleaned_data['first_name'], 'John')
- self.assertEqual(f.cleaned_data['last_name'], 'Lennon')
+ self.assertEqual(f.cleaned_data["nick_name"], "")
+ self.assertEqual(f.cleaned_data["first_name"], "John")
+ self.assertEqual(f.cleaned_data["last_name"], "Lennon")
# For DateFields, it's set to None.
class OptionalPersonForm(Form):
@@ -342,19 +380,19 @@ class FormsTestCase(SimpleTestCase):
last_name = CharField()
birth_date = DateField(required=False)
- data = {'first_name': 'John', 'last_name': 'Lennon'}
+ data = {"first_name": "John", "last_name": "Lennon"}
f = OptionalPersonForm(data)
self.assertTrue(f.is_valid())
- self.assertIsNone(f.cleaned_data['birth_date'])
- self.assertEqual(f.cleaned_data['first_name'], 'John')
- self.assertEqual(f.cleaned_data['last_name'], 'Lennon')
+ self.assertIsNone(f.cleaned_data["birth_date"])
+ self.assertEqual(f.cleaned_data["first_name"], "John")
+ self.assertEqual(f.cleaned_data["last_name"], "Lennon")
def test_auto_id(self):
# "auto_id" tells the Form to add an "id" attribute to each form element.
# If it's a string that contains '%s', Django will use that as a format string
# into which the field's name will be inserted. It will also put a <label> around
# the human-readable labels for a field.
- p = Person(auto_id='%s_id')
+ p = Person(auto_id="%s_id")
self.assertHTMLEqual(
p.as_table(),
"""<tr><th><label for="first_name_id">First name:</label></th><td>
@@ -362,7 +400,7 @@ class FormsTestCase(SimpleTestCase):
<tr><th><label for="last_name_id">Last name:</label></th><td>
<input type="text" name="last_name" id="last_name_id" required></td></tr>
<tr><th><label for="birthday_id">Birthday:</label></th><td>
-<input type="text" name="birthday" id="birthday_id" required></td></tr>"""
+<input type="text" name="birthday" id="birthday_id" required></td></tr>""",
)
self.assertHTMLEqual(
p.as_ul(),
@@ -371,7 +409,7 @@ class FormsTestCase(SimpleTestCase):
<li><label for="last_name_id">Last name:</label>
<input type="text" name="last_name" id="last_name_id" required></li>
<li><label for="birthday_id">Birthday:</label>
-<input type="text" name="birthday" id="birthday_id" required></li>"""
+<input type="text" name="birthday" id="birthday_id" required></li>""",
)
self.assertHTMLEqual(
p.as_p(),
@@ -380,7 +418,7 @@ class FormsTestCase(SimpleTestCase):
<p><label for="last_name_id">Last name:</label>
<input type="text" name="last_name" id="last_name_id" required></p>
<p><label for="birthday_id">Birthday:</label>
-<input type="text" name="birthday" id="birthday_id" required></p>"""
+<input type="text" name="birthday" id="birthday_id" required></p>""",
)
def test_auto_id_true(self):
@@ -394,7 +432,7 @@ class FormsTestCase(SimpleTestCase):
<li><label for="last_name">Last name:</label>
<input type="text" name="last_name" id="last_name" required></li>
<li><label for="birthday">Birthday:</label>
-<input type="text" name="birthday" id="birthday" required></li>"""
+<input type="text" name="birthday" id="birthday" required></li>""",
)
def test_auto_id_false(self):
@@ -405,7 +443,7 @@ class FormsTestCase(SimpleTestCase):
p.as_ul(),
"""<li>First name: <input type="text" name="first_name" required></li>
<li>Last name: <input type="text" name="last_name" required></li>
-<li>Birthday: <input type="text" name="birthday" required></li>"""
+<li>Birthday: <input type="text" name="birthday" required></li>""",
)
def test_id_on_field(self):
@@ -417,7 +455,7 @@ class FormsTestCase(SimpleTestCase):
"""<li><label for="first_name_id">First name:</label>
<input type="text" id="first_name_id" name="first_name" required></li>
<li>Last name: <input type="text" name="last_name" required></li>
-<li>Birthday: <input type="text" name="birthday" required></li>"""
+<li>Birthday: <input type="text" name="birthday" required></li>""",
)
def test_auto_id_on_form_and_field(self):
@@ -431,7 +469,7 @@ class FormsTestCase(SimpleTestCase):
<li><label for="last_name">Last name:</label>
<input type="text" name="last_name" id="last_name" required></li>
<li><label for="birthday">Birthday:</label>
-<input type="text" name="birthday" id="birthday" required></li>"""
+<input type="text" name="birthday" id="birthday" required></li>""",
)
def test_various_boolean_values(self):
@@ -440,38 +478,55 @@ class FormsTestCase(SimpleTestCase):
get_spam = BooleanField()
f = SignupForm(auto_id=False)
- self.assertHTMLEqual(str(f['email']), '<input type="email" name="email" required>')
- self.assertHTMLEqual(str(f['get_spam']), '<input type="checkbox" name="get_spam" required>')
+ self.assertHTMLEqual(
+ str(f["email"]), '<input type="email" name="email" required>'
+ )
+ self.assertHTMLEqual(
+ str(f["get_spam"]), '<input type="checkbox" name="get_spam" required>'
+ )
- f = SignupForm({'email': 'test@example.com', 'get_spam': True}, auto_id=False)
- self.assertHTMLEqual(str(f['email']), '<input type="email" name="email" value="test@example.com" required>')
+ f = SignupForm({"email": "test@example.com", "get_spam": True}, auto_id=False)
+ self.assertHTMLEqual(
+ str(f["email"]),
+ '<input type="email" name="email" value="test@example.com" required>',
+ )
self.assertHTMLEqual(
- str(f['get_spam']),
+ str(f["get_spam"]),
'<input checked type="checkbox" name="get_spam" required>',
)
# 'True' or 'true' should be rendered without a value attribute
- f = SignupForm({'email': 'test@example.com', 'get_spam': 'True'}, auto_id=False)
+ f = SignupForm({"email": "test@example.com", "get_spam": "True"}, auto_id=False)
self.assertHTMLEqual(
- str(f['get_spam']),
+ str(f["get_spam"]),
'<input checked type="checkbox" name="get_spam" required>',
)
- f = SignupForm({'email': 'test@example.com', 'get_spam': 'true'}, auto_id=False)
+ f = SignupForm({"email": "test@example.com", "get_spam": "true"}, auto_id=False)
self.assertHTMLEqual(
- str(f['get_spam']), '<input checked type="checkbox" name="get_spam" required>')
+ str(f["get_spam"]),
+ '<input checked type="checkbox" name="get_spam" required>',
+ )
# A value of 'False' or 'false' should be rendered unchecked
- f = SignupForm({'email': 'test@example.com', 'get_spam': 'False'}, auto_id=False)
- self.assertHTMLEqual(str(f['get_spam']), '<input type="checkbox" name="get_spam" required>')
+ f = SignupForm(
+ {"email": "test@example.com", "get_spam": "False"}, auto_id=False
+ )
+ self.assertHTMLEqual(
+ str(f["get_spam"]), '<input type="checkbox" name="get_spam" required>'
+ )
- f = SignupForm({'email': 'test@example.com', 'get_spam': 'false'}, auto_id=False)
- self.assertHTMLEqual(str(f['get_spam']), '<input type="checkbox" name="get_spam" required>')
+ f = SignupForm(
+ {"email": "test@example.com", "get_spam": "false"}, auto_id=False
+ )
+ self.assertHTMLEqual(
+ str(f["get_spam"]), '<input type="checkbox" name="get_spam" required>'
+ )
# A value of '0' should be interpreted as a True value (#16820)
- f = SignupForm({'email': 'test@example.com', 'get_spam': '0'})
+ f = SignupForm({"email": "test@example.com", "get_spam": "0"})
self.assertTrue(f.is_valid())
- self.assertTrue(f.cleaned_data.get('get_spam'))
+ self.assertTrue(f.cleaned_data.get("get_spam"))
def test_widget_output(self):
# Any Field can have a Widget class passed to its constructor:
@@ -480,85 +535,122 @@ class FormsTestCase(SimpleTestCase):
message = CharField(widget=Textarea)
f = ContactForm(auto_id=False)
- self.assertHTMLEqual(str(f['subject']), '<input type="text" name="subject" required>')
- self.assertHTMLEqual(str(f['message']), '<textarea name="message" rows="10" cols="40" required></textarea>')
+ self.assertHTMLEqual(
+ str(f["subject"]), '<input type="text" name="subject" required>'
+ )
+ self.assertHTMLEqual(
+ str(f["message"]),
+ '<textarea name="message" rows="10" cols="40" required></textarea>',
+ )
# as_textarea(), as_text() and as_hidden() are shortcuts for changing the output
# widget type:
self.assertHTMLEqual(
- f['subject'].as_textarea(),
+ f["subject"].as_textarea(),
'<textarea name="subject" rows="10" cols="40" required></textarea>',
)
- self.assertHTMLEqual(f['message'].as_text(), '<input type="text" name="message" required>')
- self.assertHTMLEqual(f['message'].as_hidden(), '<input type="hidden" name="message">')
+ self.assertHTMLEqual(
+ f["message"].as_text(), '<input type="text" name="message" required>'
+ )
+ self.assertHTMLEqual(
+ f["message"].as_hidden(), '<input type="hidden" name="message">'
+ )
# The 'widget' parameter to a Field can also be an instance:
class ContactForm(Form):
subject = CharField()
- message = CharField(widget=Textarea(attrs={'rows': 80, 'cols': 20}))
+ message = CharField(widget=Textarea(attrs={"rows": 80, "cols": 20}))
f = ContactForm(auto_id=False)
- self.assertHTMLEqual(str(f['message']), '<textarea name="message" rows="80" cols="20" required></textarea>')
+ self.assertHTMLEqual(
+ str(f["message"]),
+ '<textarea name="message" rows="80" cols="20" required></textarea>',
+ )
# Instance-level attrs are *not* carried over to as_textarea(), as_text() and
# as_hidden():
- self.assertHTMLEqual(f['message'].as_text(), '<input type="text" name="message" required>')
- f = ContactForm({'subject': 'Hello', 'message': 'I love you.'}, auto_id=False)
self.assertHTMLEqual(
- f['subject'].as_textarea(),
- '<textarea rows="10" cols="40" name="subject" required>Hello</textarea>'
+ f["message"].as_text(), '<input type="text" name="message" required>'
+ )
+ f = ContactForm({"subject": "Hello", "message": "I love you."}, auto_id=False)
+ self.assertHTMLEqual(
+ f["subject"].as_textarea(),
+ '<textarea rows="10" cols="40" name="subject" required>Hello</textarea>',
)
self.assertHTMLEqual(
- f['message'].as_text(),
+ f["message"].as_text(),
'<input type="text" name="message" value="I love you." required>',
)
- self.assertHTMLEqual(f['message'].as_hidden(), '<input type="hidden" name="message" value="I love you.">')
+ self.assertHTMLEqual(
+ f["message"].as_hidden(),
+ '<input type="hidden" name="message" value="I love you.">',
+ )
def test_forms_with_choices(self):
# For a form with a <select>, use ChoiceField:
class FrameworkForm(Form):
name = CharField()
- language = ChoiceField(choices=[('P', 'Python'), ('J', 'Java')])
+ language = ChoiceField(choices=[("P", "Python"), ("J", "Java")])
f = FrameworkForm(auto_id=False)
- self.assertHTMLEqual(str(f['language']), """<select name="language">
+ self.assertHTMLEqual(
+ str(f["language"]),
+ """<select name="language">
<option value="P">Python</option>
<option value="J">Java</option>
-</select>""")
- f = FrameworkForm({'name': 'Django', 'language': 'P'}, auto_id=False)
- self.assertHTMLEqual(str(f['language']), """<select name="language">
+</select>""",
+ )
+ f = FrameworkForm({"name": "Django", "language": "P"}, auto_id=False)
+ self.assertHTMLEqual(
+ str(f["language"]),
+ """<select name="language">
<option value="P" selected>Python</option>
<option value="J">Java</option>
-</select>""")
+</select>""",
+ )
# A subtlety: If one of the choices' value is the empty string and the form is
# unbound, then the <option> for the empty-string choice will get selected.
class FrameworkForm(Form):
name = CharField()
- language = ChoiceField(choices=[('', '------'), ('P', 'Python'), ('J', 'Java')])
+ language = ChoiceField(
+ choices=[("", "------"), ("P", "Python"), ("J", "Java")]
+ )
f = FrameworkForm(auto_id=False)
- self.assertHTMLEqual(str(f['language']), """<select name="language" required>
+ self.assertHTMLEqual(
+ str(f["language"]),
+ """<select name="language" required>
<option value="" selected>------</option>
<option value="P">Python</option>
<option value="J">Java</option>
-</select>""")
+</select>""",
+ )
# You can specify widget attributes in the Widget constructor.
class FrameworkForm(Form):
name = CharField()
- language = ChoiceField(choices=[('P', 'Python'), ('J', 'Java')], widget=Select(attrs={'class': 'foo'}))
+ language = ChoiceField(
+ choices=[("P", "Python"), ("J", "Java")],
+ widget=Select(attrs={"class": "foo"}),
+ )
f = FrameworkForm(auto_id=False)
- self.assertHTMLEqual(str(f['language']), """<select class="foo" name="language">
+ self.assertHTMLEqual(
+ str(f["language"]),
+ """<select class="foo" name="language">
<option value="P">Python</option>
<option value="J">Java</option>
-</select>""")
- f = FrameworkForm({'name': 'Django', 'language': 'P'}, auto_id=False)
- self.assertHTMLEqual(str(f['language']), """<select class="foo" name="language">
+</select>""",
+ )
+ f = FrameworkForm({"name": "Django", "language": "P"}, auto_id=False)
+ self.assertHTMLEqual(
+ str(f["language"]),
+ """<select class="foo" name="language">
<option value="P" selected>Python</option>
<option value="J">Java</option>
-</select>""")
+</select>""",
+ )
# When passing a custom widget instance to ChoiceField, note that setting
# 'choices' on the widget is meaningless. The widget will use the choices
@@ -566,20 +658,28 @@ class FormsTestCase(SimpleTestCase):
class FrameworkForm(Form):
name = CharField()
language = ChoiceField(
- choices=[('P', 'Python'), ('J', 'Java')],
- widget=Select(choices=[('R', 'Ruby'), ('P', 'Perl')], attrs={'class': 'foo'}),
+ choices=[("P", "Python"), ("J", "Java")],
+ widget=Select(
+ choices=[("R", "Ruby"), ("P", "Perl")], attrs={"class": "foo"}
+ ),
)
f = FrameworkForm(auto_id=False)
- self.assertHTMLEqual(str(f['language']), """<select class="foo" name="language">
+ self.assertHTMLEqual(
+ str(f["language"]),
+ """<select class="foo" name="language">
<option value="P">Python</option>
<option value="J">Java</option>
-</select>""")
- f = FrameworkForm({'name': 'Django', 'language': 'P'}, auto_id=False)
- self.assertHTMLEqual(str(f['language']), """<select class="foo" name="language">
+</select>""",
+ )
+ f = FrameworkForm({"name": "Django", "language": "P"}, auto_id=False)
+ self.assertHTMLEqual(
+ str(f["language"]),
+ """<select class="foo" name="language">
<option value="P" selected>Python</option>
<option value="J">Java</option>
-</select>""")
+</select>""",
+ )
# You can set a ChoiceField's choices after the fact.
class FrameworkForm(Form):
@@ -587,44 +687,59 @@ class FormsTestCase(SimpleTestCase):
language = ChoiceField()
f = FrameworkForm(auto_id=False)
- self.assertHTMLEqual(str(f['language']), """<select name="language">
-</select>""")
- f.fields['language'].choices = [('P', 'Python'), ('J', 'Java')]
- self.assertHTMLEqual(str(f['language']), """<select name="language">
+ self.assertHTMLEqual(
+ str(f["language"]),
+ """<select name="language">
+</select>""",
+ )
+ f.fields["language"].choices = [("P", "Python"), ("J", "Java")]
+ self.assertHTMLEqual(
+ str(f["language"]),
+ """<select name="language">
<option value="P">Python</option>
<option value="J">Java</option>
-</select>""")
+</select>""",
+ )
def test_forms_with_radio(self):
# Add widget=RadioSelect to use that widget with a ChoiceField.
f = FrameworkForm(auto_id=False)
- self.assertHTMLEqual(str(f['language']), """<div>
+ self.assertHTMLEqual(
+ str(f["language"]),
+ """<div>
<div><label><input type="radio" name="language" value="P" required> Python</label></div>
<div><label><input type="radio" name="language" value="J" required> Java</label></div>
-</div>""")
- self.assertHTMLEqual(f.as_table(), """<tr><th>Name:</th><td><input type="text" name="name" required></td></tr>
+</div>""",
+ )
+ self.assertHTMLEqual(
+ f.as_table(),
+ """<tr><th>Name:</th><td><input type="text" name="name" required></td></tr>
<tr><th>Language:</th><td><div>
<div><label><input type="radio" name="language" value="P" required> Python</label></div>
<div><label><input type="radio" name="language" value="J" required> Java</label></div>
-</div></td></tr>""")
- self.assertHTMLEqual(f.as_ul(), """<li>Name: <input type="text" name="name" required></li>
+</div></td></tr>""",
+ )
+ self.assertHTMLEqual(
+ f.as_ul(),
+ """<li>Name: <input type="text" name="name" required></li>
<li>Language: <div>
<div><label><input type="radio" name="language" value="P" required> Python</label></div>
<div><label><input type="radio" name="language" value="J" required> Java</label></div>
-</div></li>""")
+</div></li>""",
+ )
# Regarding auto_id and <label>, RadioSelect is a special case. Each radio button
# gets a distinct ID, formed by appending an underscore plus the button's
# zero-based index.
- f = FrameworkForm(auto_id='id_%s')
+ f = FrameworkForm(auto_id="id_%s")
self.assertHTMLEqual(
- str(f['language']),
+ str(f["language"]),
"""<div id="id_language">
<div><label for="id_language_0"><input type="radio" id="id_language_0" value="P" name="language" required>
Python</label></div>
<div><label for="id_language_1"><input type="radio" id="id_language_1" value="J" name="language" required>
Java</label></div>
-</div>"""
+</div>""",
)
# When RadioSelect is used with auto_id, and the whole form is printed
@@ -639,7 +754,7 @@ Java</label></div>
Python</label></div>
<div><label for="id_language_1"><input type="radio" id="id_language_1" value="J" name="language" required>
Java</label></div>
-</div></td></tr>"""
+</div></td></tr>""",
)
self.assertHTMLEqual(
f.as_ul(),
@@ -649,7 +764,7 @@ Java</label></div>
Python</label></div>
<div><label for="id_language_1"><input type="radio" id="id_language_1" value="J" name="language" required>
Java</label></div>
-</div></li>"""
+</div></li>""",
)
self.assertHTMLEqual(
f.as_p(),
@@ -659,73 +774,92 @@ Java</label></div>
Python</label></div>
<div><label for="id_language_1"><input type="radio" id="id_language_1" value="J" name="language" required>
Java</label></div>
-</div></p>"""
+</div></p>""",
)
def test_form_with_iterable_boundfield(self):
class BeatleForm(Form):
name = ChoiceField(
- choices=[('john', 'John'), ('paul', 'Paul'), ('george', 'George'), ('ringo', 'Ringo')],
+ choices=[
+ ("john", "John"),
+ ("paul", "Paul"),
+ ("george", "George"),
+ ("ringo", "Ringo"),
+ ],
widget=RadioSelect,
)
f = BeatleForm(auto_id=False)
self.assertHTMLEqual(
- '\n'.join(str(bf) for bf in f['name']),
+ "\n".join(str(bf) for bf in f["name"]),
"""<label><input type="radio" name="name" value="john" required> John</label>
<label><input type="radio" name="name" value="paul" required> Paul</label>
<label><input type="radio" name="name" value="george" required> George</label>
-<label><input type="radio" name="name" value="ringo" required> Ringo</label>"""
+<label><input type="radio" name="name" value="ringo" required> Ringo</label>""",
)
self.assertHTMLEqual(
- '\n'.join('<div>%s</div>' % bf for bf in f['name']),
+ "\n".join("<div>%s</div>" % bf for bf in f["name"]),
"""<div><label><input type="radio" name="name" value="john" required> John</label></div>
<div><label><input type="radio" name="name" value="paul" required> Paul</label></div>
<div><label><input type="radio" name="name" value="george" required> George</label></div>
-<div><label><input type="radio" name="name" value="ringo" required> Ringo</label></div>"""
+<div><label><input type="radio" name="name" value="ringo" required> Ringo</label></div>""",
)
def test_form_with_iterable_boundfield_id(self):
class BeatleForm(Form):
name = ChoiceField(
- choices=[('john', 'John'), ('paul', 'Paul'), ('george', 'George'), ('ringo', 'Ringo')],
+ choices=[
+ ("john", "John"),
+ ("paul", "Paul"),
+ ("george", "George"),
+ ("ringo", "Ringo"),
+ ],
widget=RadioSelect,
)
- fields = list(BeatleForm()['name'])
+
+ fields = list(BeatleForm()["name"])
self.assertEqual(len(fields), 4)
- self.assertEqual(fields[0].id_for_label, 'id_name_0')
- self.assertEqual(fields[0].choice_label, 'John')
+ self.assertEqual(fields[0].id_for_label, "id_name_0")
+ self.assertEqual(fields[0].choice_label, "John")
self.assertHTMLEqual(
fields[0].tag(),
- '<input type="radio" name="name" value="john" id="id_name_0" required>'
+ '<input type="radio" name="name" value="john" id="id_name_0" required>',
)
self.assertHTMLEqual(
str(fields[0]),
'<label for="id_name_0"><input type="radio" name="name" '
- 'value="john" id="id_name_0" required> John</label>'
+ 'value="john" id="id_name_0" required> John</label>',
)
- self.assertEqual(fields[1].id_for_label, 'id_name_1')
- self.assertEqual(fields[1].choice_label, 'Paul')
+ self.assertEqual(fields[1].id_for_label, "id_name_1")
+ self.assertEqual(fields[1].choice_label, "Paul")
self.assertHTMLEqual(
fields[1].tag(),
- '<input type="radio" name="name" value="paul" id="id_name_1" required>'
+ '<input type="radio" name="name" value="paul" id="id_name_1" required>',
)
self.assertHTMLEqual(
str(fields[1]),
'<label for="id_name_1"><input type="radio" name="name" '
- 'value="paul" id="id_name_1" required> Paul</label>'
+ 'value="paul" id="id_name_1" required> Paul</label>',
)
def test_iterable_boundfield_select(self):
class BeatleForm(Form):
- name = ChoiceField(choices=[('john', 'John'), ('paul', 'Paul'), ('george', 'George'), ('ringo', 'Ringo')])
- fields = list(BeatleForm(auto_id=False)['name'])
+ name = ChoiceField(
+ choices=[
+ ("john", "John"),
+ ("paul", "Paul"),
+ ("george", "George"),
+ ("ringo", "Ringo"),
+ ]
+ )
+
+ fields = list(BeatleForm(auto_id=False)["name"])
self.assertEqual(len(fields), 4)
self.assertEqual(fields[0].id_for_label, None)
- self.assertEqual(fields[0].choice_label, 'John')
+ self.assertEqual(fields[0].choice_label, "John")
self.assertHTMLEqual(fields[0].tag(), '<option value="john">John</option>')
self.assertHTMLEqual(str(fields[0]), '<option value="john">John</option>')
@@ -735,17 +869,25 @@ Java</label></div>
name = CharField()
f = BeatleForm(auto_id=False)
- self.assertHTMLEqual('\n'.join(str(bf) for bf in f['name']), '<input type="text" name="name" required>')
+ self.assertHTMLEqual(
+ "\n".join(str(bf) for bf in f["name"]),
+ '<input type="text" name="name" required>',
+ )
def test_boundfield_slice(self):
class BeatleForm(Form):
name = ChoiceField(
- choices=[('john', 'John'), ('paul', 'Paul'), ('george', 'George'), ('ringo', 'Ringo')],
+ choices=[
+ ("john", "John"),
+ ("paul", "Paul"),
+ ("george", "George"),
+ ("ringo", "Ringo"),
+ ],
widget=RadioSelect,
)
f = BeatleForm()
- bf = f['name']
+ bf = f["name"]
self.assertEqual(
[str(item) for item in bf[1:]],
[str(bf[1]), str(bf[2]), str(bf[3])],
@@ -755,17 +897,18 @@ Java</label></div>
class TestForm(Form):
name = ChoiceField(choices=[])
- field = TestForm()['name']
- msg = 'BoundField indices must be integers or slices, not str.'
+ field = TestForm()["name"]
+ msg = "BoundField indices must be integers or slices, not str."
with self.assertRaisesMessage(TypeError, msg):
- field['foo']
+ field["foo"]
def test_boundfield_bool(self):
"""BoundField without any choices (subwidgets) evaluates to True."""
+
class TestForm(Form):
name = ChoiceField(choices=[])
- self.assertIs(bool(TestForm()['name']), True)
+ self.assertIs(bool(TestForm()["name"]), True)
def test_forms_with_multiple_choice(self):
# MultipleChoiceField is a special case, as its data is required to be a list:
@@ -774,24 +917,37 @@ Java</label></div>
composers = MultipleChoiceField()
f = SongForm(auto_id=False)
- self.assertHTMLEqual(str(f['composers']), """<select multiple name="composers" required>
-</select>""")
+ self.assertHTMLEqual(
+ str(f["composers"]),
+ """<select multiple name="composers" required>
+</select>""",
+ )
class SongForm(Form):
name = CharField()
- composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')])
+ composers = MultipleChoiceField(
+ choices=[("J", "John Lennon"), ("P", "Paul McCartney")]
+ )
f = SongForm(auto_id=False)
- self.assertHTMLEqual(str(f['composers']), """<select multiple name="composers" required>
+ self.assertHTMLEqual(
+ str(f["composers"]),
+ """<select multiple name="composers" required>
<option value="J">John Lennon</option>
<option value="P">Paul McCartney</option>
-</select>""")
- f = SongForm({'name': 'Yesterday', 'composers': ['P']}, auto_id=False)
- self.assertHTMLEqual(str(f['name']), '<input type="text" name="name" value="Yesterday" required>')
- self.assertHTMLEqual(str(f['composers']), """<select multiple name="composers" required>
+</select>""",
+ )
+ f = SongForm({"name": "Yesterday", "composers": ["P"]}, auto_id=False)
+ self.assertHTMLEqual(
+ str(f["name"]), '<input type="text" name="name" value="Yesterday" required>'
+ )
+ self.assertHTMLEqual(
+ str(f["composers"]),
+ """<select multiple name="composers" required>
<option value="J">John Lennon</option>
<option value="P" selected>Paul McCartney</option>
-</select>""")
+</select>""",
+ )
f = SongForm()
self.assertHTMLEqual(
f.as_table(),
@@ -801,7 +957,7 @@ Java</label></div>
'<td><select name="composers" required id="id_composers" multiple>'
'<option value="J">John Lennon</option>'
'<option value="P">Paul McCartney</option>'
- '</select></td></tr>',
+ "</select></td></tr>",
)
self.assertHTMLEqual(
f.as_ul(),
@@ -811,7 +967,7 @@ Java</label></div>
'<select name="composers" required id="id_composers" multiple>'
'<option value="J">John Lennon</option>'
'<option value="P">Paul McCartney</option>'
- '</select></li>',
+ "</select></li>",
)
self.assertHTMLEqual(
f.as_p(),
@@ -821,7 +977,7 @@ Java</label></div>
'<select name="composers" required id="id_composers" multiple>'
'<option value="J">John Lennon</option>'
'<option value="P">Paul McCartney</option>'
- '</select></p>',
+ "</select></p>",
)
def test_multiple_checkbox_render(self):
@@ -837,7 +993,7 @@ Java</label></div>
'<div><label for="id_composers_1">'
'<input type="checkbox" name="composers" value="P" '
'id="id_composers_1">Paul McCartney</label></div>'
- '</div></td></tr>',
+ "</div></td></tr>",
)
self.assertHTMLEqual(
f.as_ul(),
@@ -850,7 +1006,7 @@ Java</label></div>
'<div><label for="id_composers_1">'
'<input type="checkbox" name="composers" value="P" '
'id="id_composers_1">Paul McCartney</label></div>'
- '</div></li>',
+ "</div></li>",
)
self.assertHTMLEqual(
f.as_p(),
@@ -863,7 +1019,7 @@ Java</label></div>
'<div><label for="id_composers_1">'
'<input type="checkbox" name="composers" value="P" '
'id="id_composers_1">Paul McCartney</label></div>'
- '</div></p>',
+ "</div></p>",
)
def test_form_with_disabled_fields(self):
@@ -877,82 +1033,101 @@ Java</label></div>
# Disabled fields are generally not transmitted by user agents.
# The value from the form's initial data is used.
- f1 = PersonForm({'name': 'John Doe'}, initial={'birthday': datetime.date(1974, 8, 16)})
- f2 = PersonFormFieldInitial({'name': 'John Doe'})
+ f1 = PersonForm(
+ {"name": "John Doe"}, initial={"birthday": datetime.date(1974, 8, 16)}
+ )
+ f2 = PersonFormFieldInitial({"name": "John Doe"})
for form in (f1, f2):
self.assertTrue(form.is_valid())
self.assertEqual(
form.cleaned_data,
- {'birthday': datetime.date(1974, 8, 16), 'name': 'John Doe'}
+ {"birthday": datetime.date(1974, 8, 16), "name": "John Doe"},
)
# Values provided in the form's data are ignored.
- data = {'name': 'John Doe', 'birthday': '1984-11-10'}
- f1 = PersonForm(data, initial={'birthday': datetime.date(1974, 8, 16)})
+ data = {"name": "John Doe", "birthday": "1984-11-10"}
+ f1 = PersonForm(data, initial={"birthday": datetime.date(1974, 8, 16)})
f2 = PersonFormFieldInitial(data)
for form in (f1, f2):
self.assertTrue(form.is_valid())
self.assertEqual(
form.cleaned_data,
- {'birthday': datetime.date(1974, 8, 16), 'name': 'John Doe'}
+ {"birthday": datetime.date(1974, 8, 16), "name": "John Doe"},
)
# Initial data remains present on invalid forms.
data = {}
- f1 = PersonForm(data, initial={'birthday': datetime.date(1974, 8, 16)})
+ f1 = PersonForm(data, initial={"birthday": datetime.date(1974, 8, 16)})
f2 = PersonFormFieldInitial(data)
for form in (f1, f2):
self.assertFalse(form.is_valid())
- self.assertEqual(form['birthday'].value(), datetime.date(1974, 8, 16))
+ self.assertEqual(form["birthday"].value(), datetime.date(1974, 8, 16))
def test_hidden_data(self):
class SongForm(Form):
name = CharField()
- composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')])
+ composers = MultipleChoiceField(
+ choices=[("J", "John Lennon"), ("P", "Paul McCartney")]
+ )
# MultipleChoiceField rendered as_hidden() is a special case. Because it can
# have multiple values, its as_hidden() renders multiple <input type="hidden">
# tags.
- f = SongForm({'name': 'Yesterday', 'composers': ['P']}, auto_id=False)
- self.assertHTMLEqual(f['composers'].as_hidden(), '<input type="hidden" name="composers" value="P">')
- f = SongForm({'name': 'From Me To You', 'composers': ['P', 'J']}, auto_id=False)
- self.assertHTMLEqual(f['composers'].as_hidden(), """<input type="hidden" name="composers" value="P">
-<input type="hidden" name="composers" value="J">""")
+ f = SongForm({"name": "Yesterday", "composers": ["P"]}, auto_id=False)
+ self.assertHTMLEqual(
+ f["composers"].as_hidden(),
+ '<input type="hidden" name="composers" value="P">',
+ )
+ f = SongForm({"name": "From Me To You", "composers": ["P", "J"]}, auto_id=False)
+ self.assertHTMLEqual(
+ f["composers"].as_hidden(),
+ """<input type="hidden" name="composers" value="P">
+<input type="hidden" name="composers" value="J">""",
+ )
# DateTimeField rendered as_hidden() is special too
class MessageForm(Form):
when = SplitDateTimeField()
- f = MessageForm({'when_0': '1992-01-01', 'when_1': '01:01'})
+ f = MessageForm({"when_0": "1992-01-01", "when_1": "01:01"})
self.assertTrue(f.is_valid())
self.assertHTMLEqual(
- str(f['when']),
+ str(f["when"]),
'<input type="text" name="when_0" value="1992-01-01" id="id_when_0" required>'
- '<input type="text" name="when_1" value="01:01" id="id_when_1" required>'
+ '<input type="text" name="when_1" value="01:01" id="id_when_1" required>',
)
self.assertHTMLEqual(
- f['when'].as_hidden(),
+ f["when"].as_hidden(),
'<input type="hidden" name="when_0" value="1992-01-01" id="id_when_0">'
- '<input type="hidden" name="when_1" value="01:01" id="id_when_1">'
+ '<input type="hidden" name="when_1" value="01:01" id="id_when_1">',
)
def test_multiple_choice_checkbox(self):
# MultipleChoiceField can also be used with the CheckboxSelectMultiple widget.
f = SongForm(auto_id=False)
- self.assertHTMLEqual(str(f['composers']), """<div>
+ self.assertHTMLEqual(
+ str(f["composers"]),
+ """<div>
<div><label><input type="checkbox" name="composers" value="J"> John Lennon</label></div>
<div><label><input type="checkbox" name="composers" value="P"> Paul McCartney</label></div>
-</div>""")
- f = SongForm({'composers': ['J']}, auto_id=False)
- self.assertHTMLEqual(str(f['composers']), """<div>
+</div>""",
+ )
+ f = SongForm({"composers": ["J"]}, auto_id=False)
+ self.assertHTMLEqual(
+ str(f["composers"]),
+ """<div>
<div><label><input checked type="checkbox" name="composers" value="J"> John Lennon</label></div>
<div><label><input type="checkbox" name="composers" value="P"> Paul McCartney</label></div>
-</div>""")
- f = SongForm({'composers': ['J', 'P']}, auto_id=False)
- self.assertHTMLEqual(str(f['composers']), """<div>
+</div>""",
+ )
+ f = SongForm({"composers": ["J", "P"]}, auto_id=False)
+ self.assertHTMLEqual(
+ str(f["composers"]),
+ """<div>
<div><label><input checked type="checkbox" name="composers" value="J"> John Lennon</label></div>
<div><label><input checked type="checkbox" name="composers" value="P"> Paul McCartney</label></div>
-</div>""")
+</div>""",
+ )
def test_checkbox_auto_id(self):
# Regarding auto_id, CheckboxSelectMultiple is a special case. Each checkbox
@@ -961,19 +1136,19 @@ Java</label></div>
class SongForm(Form):
name = CharField()
composers = MultipleChoiceField(
- choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')],
+ choices=[("J", "John Lennon"), ("P", "Paul McCartney")],
widget=CheckboxSelectMultiple,
)
- f = SongForm(auto_id='%s_id')
+ f = SongForm(auto_id="%s_id")
self.assertHTMLEqual(
- str(f['composers']),
+ str(f["composers"]),
"""<div id="composers_id">
<div><label for="composers_id_0">
<input type="checkbox" name="composers" value="J" id="composers_id_0"> John Lennon</label></div>
<div><label for="composers_id_1">
<input type="checkbox" name="composers" value="P" id="composers_id_1"> Paul McCartney</label></div>
-</div>"""
+</div>""",
)
def test_multiple_choice_list_data(self):
@@ -982,33 +1157,33 @@ Java</label></div>
class SongForm(Form):
name = CharField()
composers = MultipleChoiceField(
- choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')],
+ choices=[("J", "John Lennon"), ("P", "Paul McCartney")],
widget=CheckboxSelectMultiple,
)
- data = {'name': 'Yesterday', 'composers': ['J', 'P']}
+ data = {"name": "Yesterday", "composers": ["J", "P"]}
f = SongForm(data)
self.assertEqual(f.errors, {})
- data = QueryDict('name=Yesterday&composers=J&composers=P')
+ data = QueryDict("name=Yesterday&composers=J&composers=P")
f = SongForm(data)
self.assertEqual(f.errors, {})
- data = MultiValueDict({'name': ['Yesterday'], 'composers': ['J', 'P']})
+ data = MultiValueDict({"name": ["Yesterday"], "composers": ["J", "P"]})
f = SongForm(data)
self.assertEqual(f.errors, {})
# SelectMultiple uses ducktyping so that MultiValueDictLike.getlist()
# is called.
- f = SongForm(MultiValueDictLike({'name': 'Yesterday', 'composers': 'J'}))
+ f = SongForm(MultiValueDictLike({"name": "Yesterday", "composers": "J"}))
self.assertEqual(f.errors, {})
- self.assertEqual(f.cleaned_data['composers'], ['J'])
+ self.assertEqual(f.cleaned_data["composers"], ["J"])
def test_multiple_hidden(self):
class SongForm(Form):
name = CharField()
composers = MultipleChoiceField(
- choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')],
+ choices=[("J", "John Lennon"), ("P", "Paul McCartney")],
widget=CheckboxSelectMultiple,
)
@@ -1016,36 +1191,39 @@ Java</label></div>
class SongFormHidden(Form):
name = CharField()
composers = MultipleChoiceField(
- choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')],
+ choices=[("J", "John Lennon"), ("P", "Paul McCartney")],
widget=MultipleHiddenInput,
)
- f = SongFormHidden(MultiValueDict({'name': ['Yesterday'], 'composers': ['J', 'P']}), auto_id=False)
+ f = SongFormHidden(
+ MultiValueDict({"name": ["Yesterday"], "composers": ["J", "P"]}),
+ auto_id=False,
+ )
self.assertHTMLEqual(
f.as_ul(),
"""<li>Name: <input type="text" name="name" value="Yesterday" required>
<input type="hidden" name="composers" value="J">
-<input type="hidden" name="composers" value="P"></li>"""
+<input type="hidden" name="composers" value="P"></li>""",
)
# When using CheckboxSelectMultiple, the framework expects a list of input and
# returns a list of input.
- f = SongForm({'name': 'Yesterday'}, auto_id=False)
- self.assertEqual(f.errors['composers'], ['This field is required.'])
- f = SongForm({'name': 'Yesterday', 'composers': ['J']}, auto_id=False)
+ f = SongForm({"name": "Yesterday"}, auto_id=False)
+ self.assertEqual(f.errors["composers"], ["This field is required."])
+ f = SongForm({"name": "Yesterday", "composers": ["J"]}, auto_id=False)
self.assertEqual(f.errors, {})
- self.assertEqual(f.cleaned_data['composers'], ['J'])
- self.assertEqual(f.cleaned_data['name'], 'Yesterday')
- f = SongForm({'name': 'Yesterday', 'composers': ['J', 'P']}, auto_id=False)
+ self.assertEqual(f.cleaned_data["composers"], ["J"])
+ self.assertEqual(f.cleaned_data["name"], "Yesterday")
+ f = SongForm({"name": "Yesterday", "composers": ["J", "P"]}, auto_id=False)
self.assertEqual(f.errors, {})
- self.assertEqual(f.cleaned_data['composers'], ['J', 'P'])
- self.assertEqual(f.cleaned_data['name'], 'Yesterday')
+ self.assertEqual(f.cleaned_data["composers"], ["J", "P"])
+ self.assertEqual(f.cleaned_data["name"], "Yesterday")
# MultipleHiddenInput uses ducktyping so that
# MultiValueDictLike.getlist() is called.
- f = SongForm(MultiValueDictLike({'name': 'Yesterday', 'composers': 'J'}))
+ f = SongForm(MultiValueDictLike({"name": "Yesterday", "composers": "J"}))
self.assertEqual(f.errors, {})
- self.assertEqual(f.cleaned_data['composers'], ['J'])
+ self.assertEqual(f.cleaned_data["composers"], ["J"])
def test_escaping(self):
# Validation errors are HTML-escaped when output as HTML.
@@ -1054,18 +1232,25 @@ Java</label></div>
special_safe_name = CharField(label=mark_safe("<em>Special</em> Field"))
def clean_special_name(self):
- raise ValidationError("Something's wrong with '%s'" % self.cleaned_data['special_name'])
+ raise ValidationError(
+ "Something's wrong with '%s'" % self.cleaned_data["special_name"]
+ )
def clean_special_safe_name(self):
raise ValidationError(
- mark_safe("'<b>%s</b>' is a safe string" % self.cleaned_data['special_safe_name'])
+ mark_safe(
+ "'<b>%s</b>' is a safe string"
+ % self.cleaned_data["special_safe_name"]
+ )
)
- f = EscapingForm({
- 'special_name':
- "Nothing to escape",
- 'special_safe_name': "Nothing to escape",
- }, auto_id=False)
+ f = EscapingForm(
+ {
+ "special_name": "Nothing to escape",
+ "special_safe_name": "Nothing to escape",
+ },
+ auto_id=False,
+ )
self.assertHTMLEqual(
f.as_table(),
"""<tr><th>&lt;em&gt;Special&lt;/em&gt; Field:</th><td>
@@ -1073,12 +1258,15 @@ Java</label></div>
<input type="text" name="special_name" value="Nothing to escape" required></td></tr>
<tr><th><em>Special</em> Field:</th><td>
<ul class="errorlist"><li>'<b>Nothing to escape</b>' is a safe string</li></ul>
-<input type="text" name="special_safe_name" value="Nothing to escape" required></td></tr>"""
+<input type="text" name="special_safe_name" value="Nothing to escape" required></td></tr>""",
+ )
+ f = EscapingForm(
+ {
+ "special_name": "Should escape < & > and <script>alert('xss')</script>",
+ "special_safe_name": "<i>Do not escape</i>",
+ },
+ auto_id=False,
)
- f = EscapingForm({
- 'special_name': "Should escape < & > and <script>alert('xss')</script>",
- 'special_safe_name': "<i>Do not escape</i>"
- }, auto_id=False)
self.assertHTMLEqual(
f.as_table(),
"""<tr><th>&lt;em&gt;Special&lt;/em&gt; Field:</th><td>
@@ -1088,7 +1276,7 @@ Java</label></div>
value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt;/script&gt;" required></td></tr>
<tr><th><em>Special</em> Field:</th><td>
<ul class="errorlist"><li>'<b><i>Do not escape</i></b>' is a safe string</li></ul>
-<input type="text" name="special_safe_name" value="&lt;i&gt;Do not escape&lt;/i&gt;" required></td></tr>"""
+<input type="text" name="special_safe_name" value="&lt;i&gt;Do not escape&lt;/i&gt;" required></td></tr>""",
)
def test_validating_multiple_fields(self):
@@ -1105,25 +1293,36 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
password2 = CharField(widget=PasswordInput)
def clean_password2(self):
- if (self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and
- self.cleaned_data['password1'] != self.cleaned_data['password2']):
- raise ValidationError('Please make sure your passwords match.')
+ if (
+ self.cleaned_data.get("password1")
+ and self.cleaned_data.get("password2")
+ and self.cleaned_data["password1"] != self.cleaned_data["password2"]
+ ):
+ raise ValidationError("Please make sure your passwords match.")
- return self.cleaned_data['password2']
+ return self.cleaned_data["password2"]
f = UserRegistration(auto_id=False)
self.assertEqual(f.errors, {})
f = UserRegistration({}, auto_id=False)
- self.assertEqual(f.errors['username'], ['This field is required.'])
- self.assertEqual(f.errors['password1'], ['This field is required.'])
- self.assertEqual(f.errors['password2'], ['This field is required.'])
- f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)
- self.assertEqual(f.errors['password2'], ['Please make sure your passwords match.'])
- f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False)
+ self.assertEqual(f.errors["username"], ["This field is required."])
+ self.assertEqual(f.errors["password1"], ["This field is required."])
+ self.assertEqual(f.errors["password2"], ["This field is required."])
+ f = UserRegistration(
+ {"username": "adrian", "password1": "foo", "password2": "bar"},
+ auto_id=False,
+ )
+ self.assertEqual(
+ f.errors["password2"], ["Please make sure your passwords match."]
+ )
+ f = UserRegistration(
+ {"username": "adrian", "password1": "foo", "password2": "foo"},
+ auto_id=False,
+ )
self.assertEqual(f.errors, {})
- self.assertEqual(f.cleaned_data['username'], 'adrian')
- self.assertEqual(f.cleaned_data['password1'], 'foo')
- self.assertEqual(f.cleaned_data['password2'], 'foo')
+ self.assertEqual(f.cleaned_data["username"], "adrian")
+ self.assertEqual(f.cleaned_data["password1"], "foo")
+ self.assertEqual(f.cleaned_data["password2"], "foo")
# Another way of doing multiple-field validation is by implementing the
# Form's clean() method. Usually ValidationError raised by that method
@@ -1144,26 +1343,29 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
def clean(self):
# Test raising a ValidationError as NON_FIELD_ERRORS.
- if (self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and
- self.cleaned_data['password1'] != self.cleaned_data['password2']):
- raise ValidationError('Please make sure your passwords match.')
+ if (
+ self.cleaned_data.get("password1")
+ and self.cleaned_data.get("password2")
+ and self.cleaned_data["password1"] != self.cleaned_data["password2"]
+ ):
+ raise ValidationError("Please make sure your passwords match.")
# Test raising ValidationError that targets multiple fields.
errors = {}
- if self.cleaned_data.get('password1') == 'FORBIDDEN_VALUE':
- errors['password1'] = 'Forbidden value.'
- if self.cleaned_data.get('password2') == 'FORBIDDEN_VALUE':
- errors['password2'] = ['Forbidden value.']
+ if self.cleaned_data.get("password1") == "FORBIDDEN_VALUE":
+ errors["password1"] = "Forbidden value."
+ if self.cleaned_data.get("password2") == "FORBIDDEN_VALUE":
+ errors["password2"] = ["Forbidden value."]
if errors:
raise ValidationError(errors)
# Test Form.add_error()
- if self.cleaned_data.get('password1') == 'FORBIDDEN_VALUE2':
- self.add_error(None, 'Non-field error 1.')
- self.add_error('password1', 'Forbidden value 2.')
- if self.cleaned_data.get('password2') == 'FORBIDDEN_VALUE2':
- self.add_error('password2', 'Forbidden value 2.')
- raise ValidationError('Non-field error 2.')
+ if self.cleaned_data.get("password1") == "FORBIDDEN_VALUE2":
+ self.add_error(None, "Non-field error 1.")
+ self.add_error("password1", "Forbidden value 2.")
+ if self.cleaned_data.get("password2") == "FORBIDDEN_VALUE2":
+ self.add_error("password2", "Forbidden value 2.")
+ raise ValidationError("Non-field error 2.")
return self.cleaned_data
@@ -1179,21 +1381,26 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
<tr><th>Password1:</th><td><ul class="errorlist"><li>This field is required.</li></ul>
<input type="password" name="password1" required></td></tr>
<tr><th>Password2:</th><td><ul class="errorlist"><li>This field is required.</li></ul>
-<input type="password" name="password2" required></td></tr>"""
+<input type="password" name="password2" required></td></tr>""",
)
- self.assertEqual(f.errors['username'], ['This field is required.'])
- self.assertEqual(f.errors['password1'], ['This field is required.'])
- self.assertEqual(f.errors['password2'], ['This field is required.'])
+ self.assertEqual(f.errors["username"], ["This field is required."])
+ self.assertEqual(f.errors["password1"], ["This field is required."])
+ self.assertEqual(f.errors["password2"], ["This field is required."])
- f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)
- self.assertEqual(f.errors['__all__'], ['Please make sure your passwords match.'])
+ f = UserRegistration(
+ {"username": "adrian", "password1": "foo", "password2": "bar"},
+ auto_id=False,
+ )
+ self.assertEqual(
+ f.errors["__all__"], ["Please make sure your passwords match."]
+ )
self.assertHTMLEqual(
f.as_table(),
"""<tr><td colspan="2">
<ul class="errorlist nonfield"><li>Please make sure your passwords match.</li></ul></td></tr>
<tr><th>Username:</th><td><input type="text" name="username" value="adrian" maxlength="10" required></td></tr>
<tr><th>Password1:</th><td><input type="password" name="password1" required></td></tr>
-<tr><th>Password2:</th><td><input type="password" name="password2" required></td></tr>"""
+<tr><th>Password2:</th><td><input type="password" name="password2" required></td></tr>""",
)
self.assertHTMLEqual(
f.as_ul(),
@@ -1201,34 +1408,45 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
<li>Please make sure your passwords match.</li></ul></li>
<li>Username: <input type="text" name="username" value="adrian" maxlength="10" required></li>
<li>Password1: <input type="password" name="password1" required></li>
-<li>Password2: <input type="password" name="password2" required></li>"""
+<li>Password2: <input type="password" name="password2" required></li>""",
)
- f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False)
+ f = UserRegistration(
+ {"username": "adrian", "password1": "foo", "password2": "foo"},
+ auto_id=False,
+ )
self.assertEqual(f.errors, {})
- self.assertEqual(f.cleaned_data['username'], 'adrian')
- self.assertEqual(f.cleaned_data['password1'], 'foo')
- self.assertEqual(f.cleaned_data['password2'], 'foo')
+ self.assertEqual(f.cleaned_data["username"], "adrian")
+ self.assertEqual(f.cleaned_data["password1"], "foo")
+ self.assertEqual(f.cleaned_data["password2"], "foo")
- f = UserRegistration({
- 'username': 'adrian',
- 'password1': 'FORBIDDEN_VALUE',
- 'password2': 'FORBIDDEN_VALUE',
- }, auto_id=False)
- self.assertEqual(f.errors['password1'], ['Forbidden value.'])
- self.assertEqual(f.errors['password2'], ['Forbidden value.'])
+ f = UserRegistration(
+ {
+ "username": "adrian",
+ "password1": "FORBIDDEN_VALUE",
+ "password2": "FORBIDDEN_VALUE",
+ },
+ auto_id=False,
+ )
+ self.assertEqual(f.errors["password1"], ["Forbidden value."])
+ self.assertEqual(f.errors["password2"], ["Forbidden value."])
- f = UserRegistration({
- 'username': 'adrian',
- 'password1': 'FORBIDDEN_VALUE2',
- 'password2': 'FORBIDDEN_VALUE2',
- }, auto_id=False)
- self.assertEqual(f.errors['__all__'], ['Non-field error 1.', 'Non-field error 2.'])
- self.assertEqual(f.errors['password1'], ['Forbidden value 2.'])
- self.assertEqual(f.errors['password2'], ['Forbidden value 2.'])
+ f = UserRegistration(
+ {
+ "username": "adrian",
+ "password1": "FORBIDDEN_VALUE2",
+ "password2": "FORBIDDEN_VALUE2",
+ },
+ auto_id=False,
+ )
+ self.assertEqual(
+ f.errors["__all__"], ["Non-field error 1.", "Non-field error 2."]
+ )
+ self.assertEqual(f.errors["password1"], ["Forbidden value 2."])
+ self.assertEqual(f.errors["password2"], ["Forbidden value 2."])
with self.assertRaisesMessage(ValueError, "has no field named"):
- f.add_error('missing_field', 'Some error.')
+ f.add_error("missing_field", "Some error.")
def test_update_error_dict(self):
class CodeForm(Form):
@@ -1236,27 +1454,27 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
def clean(self):
try:
- raise ValidationError({'code': [ValidationError('Code error 1.')]})
+ raise ValidationError({"code": [ValidationError("Code error 1.")]})
except ValidationError as e:
self._errors = e.update_error_dict(self._errors)
try:
- raise ValidationError({'code': [ValidationError('Code error 2.')]})
+ raise ValidationError({"code": [ValidationError("Code error 2.")]})
except ValidationError as e:
self._errors = e.update_error_dict(self._errors)
try:
- raise ValidationError({'code': forms.ErrorList(['Code error 3.'])})
+ raise ValidationError({"code": forms.ErrorList(["Code error 3."])})
except ValidationError as e:
self._errors = e.update_error_dict(self._errors)
try:
- raise ValidationError('Non-field error 1.')
+ raise ValidationError("Non-field error 1.")
except ValidationError as e:
self._errors = e.update_error_dict(self._errors)
try:
- raise ValidationError([ValidationError('Non-field error 2.')])
+ raise ValidationError([ValidationError("Non-field error 2.")])
except ValidationError as e:
self._errors = e.update_error_dict(self._errors)
@@ -1265,17 +1483,20 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
if not isinstance(error_list, self.error_class):
self._errors[field] = self.error_class(error_list)
- form = CodeForm({'code': 'hello'})
+ form = CodeForm({"code": "hello"})
# Trigger validation.
self.assertFalse(form.is_valid())
# update_error_dict didn't lose track of the ErrorDict type.
self.assertIsInstance(form._errors, forms.ErrorDict)
- self.assertEqual(dict(form.errors), {
- 'code': ['Code error 1.', 'Code error 2.', 'Code error 3.'],
- NON_FIELD_ERRORS: ['Non-field error 1.', 'Non-field error 2.'],
- })
+ self.assertEqual(
+ dict(form.errors),
+ {
+ "code": ["Code error 1.", "Code error 2.", "Code error 3."],
+ NON_FIELD_ERRORS: ["Non-field error 1.", "Non-field error 2."],
+ },
+ )
def test_has_error(self):
class UserRegistration(Form):
@@ -1284,43 +1505,46 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
password2 = CharField(widget=PasswordInput)
def clean(self):
- if (self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and
- self.cleaned_data['password1'] != self.cleaned_data['password2']):
+ if (
+ self.cleaned_data.get("password1")
+ and self.cleaned_data.get("password2")
+ and self.cleaned_data["password1"] != self.cleaned_data["password2"]
+ ):
raise ValidationError(
- 'Please make sure your passwords match.',
- code='password_mismatch',
+ "Please make sure your passwords match.",
+ code="password_mismatch",
)
f = UserRegistration(data={})
- self.assertTrue(f.has_error('password1'))
- self.assertTrue(f.has_error('password1', 'required'))
- self.assertFalse(f.has_error('password1', 'anything'))
+ self.assertTrue(f.has_error("password1"))
+ self.assertTrue(f.has_error("password1", "required"))
+ self.assertFalse(f.has_error("password1", "anything"))
- f = UserRegistration(data={'password1': 'Hi', 'password2': 'Hi'})
- self.assertTrue(f.has_error('password1'))
- self.assertTrue(f.has_error('password1', 'min_length'))
- self.assertFalse(f.has_error('password1', 'anything'))
- self.assertFalse(f.has_error('password2'))
- self.assertFalse(f.has_error('password2', 'anything'))
+ f = UserRegistration(data={"password1": "Hi", "password2": "Hi"})
+ self.assertTrue(f.has_error("password1"))
+ self.assertTrue(f.has_error("password1", "min_length"))
+ self.assertFalse(f.has_error("password1", "anything"))
+ self.assertFalse(f.has_error("password2"))
+ self.assertFalse(f.has_error("password2", "anything"))
- f = UserRegistration(data={'password1': 'Bonjour', 'password2': 'Hello'})
- self.assertFalse(f.has_error('password1'))
- self.assertFalse(f.has_error('password1', 'required'))
+ f = UserRegistration(data={"password1": "Bonjour", "password2": "Hello"})
+ self.assertFalse(f.has_error("password1"))
+ self.assertFalse(f.has_error("password1", "required"))
self.assertTrue(f.has_error(NON_FIELD_ERRORS))
- self.assertTrue(f.has_error(NON_FIELD_ERRORS, 'password_mismatch'))
- self.assertFalse(f.has_error(NON_FIELD_ERRORS, 'anything'))
+ self.assertTrue(f.has_error(NON_FIELD_ERRORS, "password_mismatch"))
+ self.assertFalse(f.has_error(NON_FIELD_ERRORS, "anything"))
def test_html_output_with_hidden_input_field_errors(self):
class TestForm(Form):
hidden_input = CharField(widget=HiddenInput)
def clean(self):
- self.add_error(None, 'Form error')
+ self.add_error(None, "Form error")
f = TestForm(data={})
error_dict = {
- 'hidden_input': ['This field is required.'],
- '__all__': ['Form error'],
+ "hidden_input": ["This field is required."],
+ "__all__": ["Form error"],
}
self.assertEqual(f.errors, error_dict)
f.as_table()
@@ -1328,19 +1552,19 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
self.assertHTMLEqual(
f.as_table(),
'<tr><td colspan="2"><ul class="errorlist nonfield"><li>Form error</li>'
- '<li>(Hidden field hidden_input) This field is required.</li></ul>'
+ "<li>(Hidden field hidden_input) This field is required.</li></ul>"
'<input type="hidden" name="hidden_input" id="id_hidden_input"></td></tr>',
)
self.assertHTMLEqual(
f.as_ul(),
'<li><ul class="errorlist nonfield"><li>Form error</li>'
- '<li>(Hidden field hidden_input) This field is required.</li></ul>'
+ "<li>(Hidden field hidden_input) This field is required.</li></ul>"
'<input type="hidden" name="hidden_input" id="id_hidden_input"></li>',
)
self.assertHTMLEqual(
f.as_p(),
'<ul class="errorlist nonfield"><li>Form error</li>'
- '<li>(Hidden field hidden_input) This field is required.</li></ul>'
+ "<li>(Hidden field hidden_input) This field is required.</li></ul>"
'<p><input type="hidden" name="hidden_input" id="id_hidden_input"></p>',
)
@@ -1354,14 +1578,14 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
- self.fields['birthday'] = DateField()
+ self.fields["birthday"] = DateField()
p = Person(auto_id=False)
self.assertHTMLEqual(
p.as_table(),
"""<tr><th>First name:</th><td><input type="text" name="first_name" required></td></tr>
<tr><th>Last name:</th><td><input type="text" name="last_name" required></td></tr>
-<tr><th>Birthday:</th><td><input type="text" name="birthday" required></td></tr>"""
+<tr><th>Birthday:</th><td><input type="text" name="birthday" required></td></tr>""",
)
# Instances of a dynamic Form do not persist fields from one Form instance to
@@ -1373,19 +1597,19 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
for field in field_list:
self.fields[field[0]] = field[1]
- field_list = [('field1', CharField()), ('field2', CharField())]
+ field_list = [("field1", CharField()), ("field2", CharField())]
my_form = MyForm(field_list=field_list)
self.assertHTMLEqual(
my_form.as_table(),
"""<tr><th>Field1:</th><td><input type="text" name="field1" required></td></tr>
-<tr><th>Field2:</th><td><input type="text" name="field2" required></td></tr>"""
+<tr><th>Field2:</th><td><input type="text" name="field2" required></td></tr>""",
)
- field_list = [('field3', CharField()), ('field4', CharField())]
+ field_list = [("field3", CharField()), ("field4", CharField())]
my_form = MyForm(field_list=field_list)
self.assertHTMLEqual(
my_form.as_table(),
"""<tr><th>Field3:</th><td><input type="text" name="field3" required></td></tr>
-<tr><th>Field4:</th><td><input type="text" name="field4" required></td></tr>"""
+<tr><th>Field4:</th><td><input type="text" name="field4" required></td></tr>""",
)
class MyForm(Form):
@@ -1398,23 +1622,23 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
for field in field_list:
self.fields[field[0]] = field[1]
- field_list = [('field1', CharField()), ('field2', CharField())]
+ field_list = [("field1", CharField()), ("field2", CharField())]
my_form = MyForm(field_list=field_list)
self.assertHTMLEqual(
my_form.as_table(),
"""<tr><th>Default field 1:</th><td><input type="text" name="default_field_1" required></td></tr>
<tr><th>Default field 2:</th><td><input type="text" name="default_field_2" required></td></tr>
<tr><th>Field1:</th><td><input type="text" name="field1" required></td></tr>
-<tr><th>Field2:</th><td><input type="text" name="field2" required></td></tr>"""
+<tr><th>Field2:</th><td><input type="text" name="field2" required></td></tr>""",
)
- field_list = [('field3', CharField()), ('field4', CharField())]
+ field_list = [("field3", CharField()), ("field4", CharField())]
my_form = MyForm(field_list=field_list)
self.assertHTMLEqual(
my_form.as_table(),
"""<tr><th>Default field 1:</th><td><input type="text" name="default_field_1" required></td></tr>
<tr><th>Default field 2:</th><td><input type="text" name="default_field_2" required></td></tr>
<tr><th>Field3:</th><td><input type="text" name="field3" required></td></tr>
-<tr><th>Field4:</th><td><input type="text" name="field4" required></td></tr>"""
+<tr><th>Field4:</th><td><input type="text" name="field4" required></td></tr>""",
)
# Similarly, changes to field attributes do not persist from one Form instance
@@ -1427,24 +1651,42 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
super().__init__(*args, **kwargs)
if names_required:
- self.fields['first_name'].required = True
- self.fields['first_name'].widget.attrs['class'] = 'required'
- self.fields['last_name'].required = True
- self.fields['last_name'].widget.attrs['class'] = 'required'
+ self.fields["first_name"].required = True
+ self.fields["first_name"].widget.attrs["class"] = "required"
+ self.fields["last_name"].required = True
+ self.fields["last_name"].widget.attrs["class"] = "required"
f = Person(names_required=False)
- self.assertEqual(f['first_name'].field.required, f['last_name'].field.required, (False, False))
- self.assertEqual(f['first_name'].field.widget.attrs, f['last_name'].field.widget.attrs, ({}, {}))
+ self.assertEqual(
+ f["first_name"].field.required,
+ f["last_name"].field.required,
+ (False, False),
+ )
+ self.assertEqual(
+ f["first_name"].field.widget.attrs,
+ f["last_name"].field.widget.attrs,
+ ({}, {}),
+ )
f = Person(names_required=True)
- self.assertEqual(f['first_name'].field.required, f['last_name'].field.required, (True, True))
self.assertEqual(
- f['first_name'].field.widget.attrs,
- f['last_name'].field.widget.attrs,
- ({'class': 'reuired'}, {'class': 'required'})
+ f["first_name"].field.required, f["last_name"].field.required, (True, True)
+ )
+ self.assertEqual(
+ f["first_name"].field.widget.attrs,
+ f["last_name"].field.widget.attrs,
+ ({"class": "reuired"}, {"class": "required"}),
)
f = Person(names_required=False)
- self.assertEqual(f['first_name'].field.required, f['last_name'].field.required, (False, False))
- self.assertEqual(f['first_name'].field.widget.attrs, f['last_name'].field.widget.attrs, ({}, {}))
+ self.assertEqual(
+ f["first_name"].field.required,
+ f["last_name"].field.required,
+ (False, False),
+ )
+ self.assertEqual(
+ f["first_name"].field.widget.attrs,
+ f["last_name"].field.widget.attrs,
+ ({}, {}),
+ )
class Person(Form):
first_name = CharField(max_length=30)
@@ -1454,49 +1696,61 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
super().__init__(*args, **kwargs)
if name_max_length:
- self.fields['first_name'].max_length = name_max_length
- self.fields['last_name'].max_length = name_max_length
+ self.fields["first_name"].max_length = name_max_length
+ self.fields["last_name"].max_length = name_max_length
f = Person(name_max_length=None)
- self.assertEqual(f['first_name'].field.max_length, f['last_name'].field.max_length, (30, 30))
+ self.assertEqual(
+ f["first_name"].field.max_length, f["last_name"].field.max_length, (30, 30)
+ )
f = Person(name_max_length=20)
- self.assertEqual(f['first_name'].field.max_length, f['last_name'].field.max_length, (20, 20))
+ self.assertEqual(
+ f["first_name"].field.max_length, f["last_name"].field.max_length, (20, 20)
+ )
f = Person(name_max_length=None)
- self.assertEqual(f['first_name'].field.max_length, f['last_name'].field.max_length, (30, 30))
+ self.assertEqual(
+ f["first_name"].field.max_length, f["last_name"].field.max_length, (30, 30)
+ )
# Similarly, choices do not persist from one Form instance to the next.
# Refs #15127.
class Person(Form):
first_name = CharField(required=False)
last_name = CharField(required=False)
- gender = ChoiceField(choices=(('f', 'Female'), ('m', 'Male')))
+ gender = ChoiceField(choices=(("f", "Female"), ("m", "Male")))
def __init__(self, allow_unspec_gender=False, *args, **kwargs):
super().__init__(*args, **kwargs)
if allow_unspec_gender:
- self.fields['gender'].choices += (('u', 'Unspecified'),)
+ self.fields["gender"].choices += (("u", "Unspecified"),)
f = Person()
- self.assertEqual(f['gender'].field.choices, [('f', 'Female'), ('m', 'Male')])
+ self.assertEqual(f["gender"].field.choices, [("f", "Female"), ("m", "Male")])
f = Person(allow_unspec_gender=True)
- self.assertEqual(f['gender'].field.choices, [('f', 'Female'), ('m', 'Male'), ('u', 'Unspecified')])
+ self.assertEqual(
+ f["gender"].field.choices,
+ [("f", "Female"), ("m", "Male"), ("u", "Unspecified")],
+ )
f = Person()
- self.assertEqual(f['gender'].field.choices, [('f', 'Female'), ('m', 'Male')])
+ self.assertEqual(f["gender"].field.choices, [("f", "Female"), ("m", "Male")])
def test_validators_independence(self):
"""
The list of form field validators can be modified without polluting
other forms.
"""
+
class MyForm(Form):
myfield = CharField(max_length=25)
f1 = MyForm()
f2 = MyForm()
- f1.fields['myfield'].validators[0] = MaxValueValidator(12)
- self.assertNotEqual(f1.fields['myfield'].validators[0], f2.fields['myfield'].validators[0])
+ f1.fields["myfield"].validators[0] = MaxValueValidator(12)
+ self.assertNotEqual(
+ f1.fields["myfield"].validators[0], f2.fields["myfield"].validators[0]
+ )
def test_hidden_widget(self):
# HiddenInput widgets are displayed differently in the as_table(), as_ul())
@@ -1515,22 +1769,23 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
"""<tr><th>First name:</th><td><input type="text" name="first_name" required></td></tr>
<tr><th>Last name:</th><td><input type="text" name="last_name" required></td></tr>
<tr><th>Birthday:</th>
-<td><input type="text" name="birthday" required><input type="hidden" name="hidden_text"></td></tr>"""
+<td><input type="text" name="birthday" required><input type="hidden" name="hidden_text"></td></tr>""",
)
self.assertHTMLEqual(
p.as_ul(),
"""<li>First name: <input type="text" name="first_name" required></li>
<li>Last name: <input type="text" name="last_name" required></li>
-<li>Birthday: <input type="text" name="birthday" required><input type="hidden" name="hidden_text"></li>"""
+<li>Birthday: <input type="text" name="birthday" required><input type="hidden" name="hidden_text"></li>""",
)
self.assertHTMLEqual(
- p.as_p(), """<p>First name: <input type="text" name="first_name" required></p>
+ p.as_p(),
+ """<p>First name: <input type="text" name="first_name" required></p>
<p>Last name: <input type="text" name="last_name" required></p>
-<p>Birthday: <input type="text" name="birthday" required><input type="hidden" name="hidden_text"></p>"""
+<p>Birthday: <input type="text" name="birthday" required><input type="hidden" name="hidden_text"></p>""",
)
# With auto_id set, a HiddenInput still gets an ID, but it doesn't get a label.
- p = Person(auto_id='id_%s')
+ p = Person(auto_id="id_%s")
self.assertHTMLEqual(
p.as_table(),
"""<tr><th><label for="id_first_name">First name:</label></th><td>
@@ -1539,7 +1794,7 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
<input type="text" name="last_name" id="id_last_name" required></td></tr>
<tr><th><label for="id_birthday">Birthday:</label></th><td>
<input type="text" name="birthday" id="id_birthday" required>
-<input type="hidden" name="hidden_text" id="id_hidden_text"></td></tr>"""
+<input type="hidden" name="hidden_text" id="id_hidden_text"></td></tr>""",
)
self.assertHTMLEqual(
p.as_ul(),
@@ -1549,7 +1804,7 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
<input type="text" name="last_name" id="id_last_name" required></li>
<li><label for="id_birthday">Birthday:</label>
<input type="text" name="birthday" id="id_birthday" required>
-<input type="hidden" name="hidden_text" id="id_hidden_text"></li>"""
+<input type="hidden" name="hidden_text" id="id_hidden_text"></li>""",
)
self.assertHTMLEqual(
p.as_p(),
@@ -1559,14 +1814,17 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
<input type="text" name="last_name" id="id_last_name" required></p>
<p><label for="id_birthday">Birthday:</label>
<input type="text" name="birthday" id="id_birthday" required>
-<input type="hidden" name="hidden_text" id="id_hidden_text"></p>"""
+<input type="hidden" name="hidden_text" id="id_hidden_text"></p>""",
)
# If a field with a HiddenInput has errors, the as_table() and as_ul() output
# will include the error message(s) with the text "(Hidden field [fieldname]) "
# prepended. This message is displayed at the top of the output, regardless of
# its field's order in the form.
- p = Person({'first_name': 'John', 'last_name': 'Lennon', 'birthday': '1940-10-9'}, auto_id=False)
+ p = Person(
+ {"first_name": "John", "last_name": "Lennon", "birthday": "1940-10-9"},
+ auto_id=False,
+ )
self.assertHTMLEqual(
p.as_table(),
"""<tr><td colspan="2">
@@ -1574,7 +1832,7 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
<tr><th>First name:</th><td><input type="text" name="first_name" value="John" required></td></tr>
<tr><th>Last name:</th><td><input type="text" name="last_name" value="Lennon" required></td></tr>
<tr><th>Birthday:</th><td><input type="text" name="birthday" value="1940-10-9" required>
-<input type="hidden" name="hidden_text"></td></tr>"""
+<input type="hidden" name="hidden_text"></td></tr>""",
)
self.assertHTMLEqual(
p.as_ul(),
@@ -1582,7 +1840,7 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
<li>First name: <input type="text" name="first_name" value="John" required></li>
<li>Last name: <input type="text" name="last_name" value="Lennon" required></li>
<li>Birthday: <input type="text" name="birthday" value="1940-10-9" required>
-<input type="hidden" name="hidden_text"></li>"""
+<input type="hidden" name="hidden_text"></li>""",
)
self.assertHTMLEqual(
p.as_p(),
@@ -1590,7 +1848,7 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
<p>First name: <input type="text" name="first_name" value="John" required></p>
<p>Last name: <input type="text" name="last_name" value="Lennon" required></p>
<p>Birthday: <input type="text" name="birthday" value="1940-10-9" required>
-<input type="hidden" name="hidden_text"></p>"""
+<input type="hidden" name="hidden_text"></p>""",
)
# A corner case: It's possible for a form to have only HiddenInputs.
@@ -1599,9 +1857,17 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
bar = CharField(widget=HiddenInput)
p = TestForm(auto_id=False)
- self.assertHTMLEqual(p.as_table(), '<input type="hidden" name="foo"><input type="hidden" name="bar">')
- self.assertHTMLEqual(p.as_ul(), '<input type="hidden" name="foo"><input type="hidden" name="bar">')
- self.assertHTMLEqual(p.as_p(), '<input type="hidden" name="foo"><input type="hidden" name="bar">')
+ self.assertHTMLEqual(
+ p.as_table(),
+ '<input type="hidden" name="foo"><input type="hidden" name="bar">',
+ )
+ self.assertHTMLEqual(
+ p.as_ul(),
+ '<input type="hidden" name="foo"><input type="hidden" name="bar">',
+ )
+ self.assertHTMLEqual(
+ p.as_p(), '<input type="hidden" name="foo"><input type="hidden" name="bar">'
+ )
def test_field_order(self):
# A Form's fields are displayed in the same order in which they were defined.
@@ -1622,7 +1888,9 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
field14 = CharField()
p = TestForm(auto_id=False)
- self.assertHTMLEqual(p.as_table(), """<tr><th>Field1:</th><td><input type="text" name="field1" required></td></tr>
+ self.assertHTMLEqual(
+ p.as_table(),
+ """<tr><th>Field1:</th><td><input type="text" name="field1" required></td></tr>
<tr><th>Field2:</th><td><input type="text" name="field2" required></td></tr>
<tr><th>Field3:</th><td><input type="text" name="field3" required></td></tr>
<tr><th>Field4:</th><td><input type="text" name="field4" required></td></tr>
@@ -1635,7 +1903,8 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
<tr><th>Field11:</th><td><input type="text" name="field11" required></td></tr>
<tr><th>Field12:</th><td><input type="text" name="field12" required></td></tr>
<tr><th>Field13:</th><td><input type="text" name="field13" required></td></tr>
-<tr><th>Field14:</th><td><input type="text" name="field14" required></td></tr>""")
+<tr><th>Field14:</th><td><input type="text" name="field14" required></td></tr>""",
+ )
def test_explicit_field_order(self):
class TestFormParent(Form):
@@ -1644,17 +1913,17 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
field4 = CharField()
field5 = CharField()
field6 = CharField()
- field_order = ['field6', 'field5', 'field4', 'field2', 'field1']
+ field_order = ["field6", "field5", "field4", "field2", "field1"]
class TestForm(TestFormParent):
field3 = CharField()
- field_order = ['field2', 'field4', 'field3', 'field5', 'field6']
+ field_order = ["field2", "field4", "field3", "field5", "field6"]
class TestFormRemove(TestForm):
field1 = None
class TestFormMissing(TestForm):
- field_order = ['field2', 'field4', 'field3', 'field5', 'field6', 'field1']
+ field_order = ["field2", "field4", "field3", "field5", "field6", "field1"]
field1 = None
class TestFormInit(TestFormParent):
@@ -1674,11 +1943,13 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
p = TestForm()
self.assertEqual(list(p.fields), TestFormMissing.field_order)
p = TestFormInit()
- order = [*TestForm.field_order, 'field1']
+ order = [*TestForm.field_order, "field1"]
self.assertEqual(list(p.fields), order)
- TestForm.field_order = ['unknown']
+ TestForm.field_order = ["unknown"]
p = TestForm()
- self.assertEqual(list(p.fields), ['field1', 'field2', 'field4', 'field5', 'field6', 'field3'])
+ self.assertEqual(
+ list(p.fields), ["field1", "field2", "field4", "field5", "field6", "field3"]
+ )
def test_form_html_attributes(self):
# Some Field classes have an effect on the HTML attributes of their associated
@@ -1686,10 +1957,12 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
# either a TextInput or PasswordInput, then the widget's rendered HTML will
# include the "maxlength" attribute.
class UserRegistration(Form):
- username = CharField(max_length=10) # uses TextInput by default
+ username = CharField(max_length=10) # uses TextInput by default
password = CharField(max_length=10, widget=PasswordInput)
- realname = CharField(max_length=10, widget=TextInput) # redundantly define widget, just to test
- address = CharField() # no max_length defined here
+ realname = CharField(
+ max_length=10, widget=TextInput
+ ) # redundantly define widget, just to test
+ address = CharField() # no max_length defined here
p = UserRegistration(auto_id=False)
self.assertHTMLEqual(
@@ -1697,21 +1970,23 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
"""<li>Username: <input type="text" name="username" maxlength="10" required></li>
<li>Password: <input type="password" name="password" maxlength="10" required></li>
<li>Realname: <input type="text" name="realname" maxlength="10" required></li>
-<li>Address: <input type="text" name="address" required></li>"""
+<li>Address: <input type="text" name="address" required></li>""",
)
# If you specify a custom "attrs" that includes the "maxlength" attribute,
# the Field's max_length attribute will override whatever "maxlength" you specify
# in "attrs".
class UserRegistration(Form):
- username = CharField(max_length=10, widget=TextInput(attrs={'maxlength': 20}))
+ username = CharField(
+ max_length=10, widget=TextInput(attrs={"maxlength": 20})
+ )
password = CharField(max_length=10, widget=PasswordInput)
p = UserRegistration(auto_id=False)
self.assertHTMLEqual(
p.as_ul(),
"""<li>Username: <input type="text" name="username" maxlength="10" required></li>
-<li>Password: <input type="password" name="password" maxlength="10" required></li>"""
+<li>Password: <input type="password" name="password" maxlength="10" required></li>""",
)
def test_specifying_labels(self):
@@ -1719,26 +1994,26 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
# class. If you don't specify 'label', Django will use the field name with
# underscores converted to spaces, and the initial letter capitalized.
class UserRegistration(Form):
- username = CharField(max_length=10, label='Your username')
+ username = CharField(max_length=10, label="Your username")
password1 = CharField(widget=PasswordInput)
- password2 = CharField(widget=PasswordInput, label='Contraseña (de nuevo)')
+ password2 = CharField(widget=PasswordInput, label="Contraseña (de nuevo)")
p = UserRegistration(auto_id=False)
self.assertHTMLEqual(
p.as_ul(),
"""<li>Your username: <input type="text" name="username" maxlength="10" required></li>
<li>Password1: <input type="password" name="password1" required></li>
-<li>Contraseña (de nuevo): <input type="password" name="password2" required></li>"""
+<li>Contraseña (de nuevo): <input type="password" name="password2" required></li>""",
)
# Labels for as_* methods will only end in a colon if they don't end in other
# punctuation already.
class Questions(Form):
- q1 = CharField(label='The first question')
- q2 = CharField(label='What is your name?')
- q3 = CharField(label='The answer to life is:')
- q4 = CharField(label='Answer this question!')
- q5 = CharField(label='The last question. Period.')
+ q1 = CharField(label="The first question")
+ q2 = CharField(label="What is your name?")
+ q3 = CharField(label="The answer to life is:")
+ q4 = CharField(label="Answer this question!")
+ q5 = CharField(label="The last question. Period.")
self.assertHTMLEqual(
Questions(auto_id=False).as_p(),
@@ -1746,7 +2021,7 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
<p>What is your name? <input type="text" name="q2" required></p>
<p>The answer to life is: <input type="text" name="q3" required></p>
<p>Answer this question! <input type="text" name="q4" required></p>
-<p>The last question. Period. <input type="text" name="q5" required></p>"""
+<p>The last question. Period. <input type="text" name="q5" required></p>""",
)
self.assertHTMLEqual(
Questions().as_p(),
@@ -1754,23 +2029,26 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
<p><label for="id_q2">What is your name?</label> <input type="text" name="q2" id="id_q2" required></p>
<p><label for="id_q3">The answer to life is:</label> <input type="text" name="q3" id="id_q3" required></p>
<p><label for="id_q4">Answer this question!</label> <input type="text" name="q4" id="id_q4" required></p>
-<p><label for="id_q5">The last question. Period.</label> <input type="text" name="q5" id="id_q5" required></p>"""
+<p><label for="id_q5">The last question. Period.</label> <input type="text" name="q5" id="id_q5" required></p>""",
)
# If a label is set to the empty string for a field, that field won't get a label.
class UserRegistration(Form):
- username = CharField(max_length=10, label='')
+ username = CharField(max_length=10, label="")
password = CharField(widget=PasswordInput)
p = UserRegistration(auto_id=False)
- self.assertHTMLEqual(p.as_ul(), """<li> <input type="text" name="username" maxlength="10" required></li>
-<li>Password: <input type="password" name="password" required></li>""")
- p = UserRegistration(auto_id='id_%s')
+ self.assertHTMLEqual(
+ p.as_ul(),
+ """<li> <input type="text" name="username" maxlength="10" required></li>
+<li>Password: <input type="password" name="password" required></li>""",
+ )
+ p = UserRegistration(auto_id="id_%s")
self.assertHTMLEqual(
p.as_ul(),
"""<li> <input id="id_username" type="text" name="username" maxlength="10" required></li>
<li><label for="id_password">Password:</label>
-<input type="password" name="password" id="id_password" required></li>"""
+<input type="password" name="password" id="id_password" required></li>""",
)
# If label is None, Django will auto-create the label from the field name. This
@@ -1783,15 +2061,15 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
self.assertHTMLEqual(
p.as_ul(),
"""<li>Username: <input type="text" name="username" maxlength="10" required></li>
-<li>Password: <input type="password" name="password" required></li>"""
+<li>Password: <input type="password" name="password" required></li>""",
)
- p = UserRegistration(auto_id='id_%s')
+ p = UserRegistration(auto_id="id_%s")
self.assertHTMLEqual(
p.as_ul(),
"""<li><label for="id_username">Username:</label>
<input id="id_username" type="text" name="username" maxlength="10" required></li>
<li><label for="id_password">Password:</label>
-<input type="password" name="password" id="id_password" required></li>"""
+<input type="password" name="password" id="id_password" required></li>""",
)
def test_label_suffix(self):
@@ -1801,31 +2079,40 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
# punctuation symbol: ., !, ? or :. If you specify a different suffix, it will
# be appended regardless of the last character of the label.
class FavoriteForm(Form):
- color = CharField(label='Favorite color?')
- animal = CharField(label='Favorite animal')
- answer = CharField(label='Secret answer', label_suffix=' =')
+ color = CharField(label="Favorite color?")
+ animal = CharField(label="Favorite animal")
+ answer = CharField(label="Secret answer", label_suffix=" =")
f = FavoriteForm(auto_id=False)
- self.assertHTMLEqual(f.as_ul(), """<li>Favorite color? <input type="text" name="color" required></li>
+ self.assertHTMLEqual(
+ f.as_ul(),
+ """<li>Favorite color? <input type="text" name="color" required></li>
<li>Favorite animal: <input type="text" name="animal" required></li>
-<li>Secret answer = <input type="text" name="answer" required></li>""")
+<li>Secret answer = <input type="text" name="answer" required></li>""",
+ )
- f = FavoriteForm(auto_id=False, label_suffix='?')
- self.assertHTMLEqual(f.as_ul(), """<li>Favorite color? <input type="text" name="color" required></li>
+ f = FavoriteForm(auto_id=False, label_suffix="?")
+ self.assertHTMLEqual(
+ f.as_ul(),
+ """<li>Favorite color? <input type="text" name="color" required></li>
<li>Favorite animal? <input type="text" name="animal" required></li>
-<li>Secret answer = <input type="text" name="answer" required></li>""")
+<li>Secret answer = <input type="text" name="answer" required></li>""",
+ )
- f = FavoriteForm(auto_id=False, label_suffix='')
- self.assertHTMLEqual(f.as_ul(), """<li>Favorite color? <input type="text" name="color" required></li>
+ f = FavoriteForm(auto_id=False, label_suffix="")
+ self.assertHTMLEqual(
+ f.as_ul(),
+ """<li>Favorite color? <input type="text" name="color" required></li>
<li>Favorite animal <input type="text" name="animal" required></li>
-<li>Secret answer = <input type="text" name="answer" required></li>""")
+<li>Secret answer = <input type="text" name="answer" required></li>""",
+ )
- f = FavoriteForm(auto_id=False, label_suffix='\u2192')
+ f = FavoriteForm(auto_id=False, label_suffix="\u2192")
self.assertHTMLEqual(
f.as_ul(),
'<li>Favorite color? <input type="text" name="color" required></li>\n'
'<li>Favorite animal\u2192 <input type="text" name="animal" required></li>\n'
- '<li>Secret answer = <input type="text" name="answer" required></li>'
+ '<li>Secret answer = <input type="text" name="answer" required></li>',
)
def test_initial_data(self):
@@ -1835,7 +2122,7 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
# empty dictionary). Also, the initial value is *not* used if data for a
# particular required field isn't provided.
class UserRegistration(Form):
- username = CharField(max_length=10, initial='django')
+ username = CharField(max_length=10, initial="django")
password = CharField(widget=PasswordInput)
# Here, we're not submitting any data, so the initial value will be displayed.)
@@ -1843,7 +2130,7 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
self.assertHTMLEqual(
p.as_ul(),
"""<li>Username: <input type="text" name="username" value="django" maxlength="10" required></li>
-<li>Password: <input type="password" name="password" required></li>"""
+<li>Password: <input type="password" name="password" required></li>""",
)
# Here, we're submitting data, so the initial value will *not* be displayed.
@@ -1853,29 +2140,29 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#x27;xss&#x27;)&lt
"""<li><ul class="errorlist"><li>This field is required.</li></ul>
Username: <input type="text" name="username" maxlength="10" required></li>
<li><ul class="errorlist"><li>This field is required.</li></ul>
-Password: <input type="password" name="password" required></li>"""
+Password: <input type="password" name="password" required></li>""",
)
- p = UserRegistration({'username': ''}, auto_id=False)
+ p = UserRegistration({"username": ""}, auto_id=False)
self.assertHTMLEqual(
p.as_ul(),
"""<li><ul class="errorlist"><li>This field is required.</li></ul>
Username: <input type="text" name="username" maxlength="10" required></li>
<li><ul class="errorlist"><li>This field is required.</li></ul>
-Password: <input type="password" name="password" required></li>"""
+Password: <input type="password" name="password" required></li>""",
)
- p = UserRegistration({'username': 'foo'}, auto_id=False)
+ p = UserRegistration({"username": "foo"}, auto_id=False)
self.assertHTMLEqual(
p.as_ul(),
"""<li>Username: <input type="text" name="username" value="foo" maxlength="10" required></li>
<li><ul class="errorlist"><li>This field is required.</li></ul>
-Password: <input type="password" name="password" required></li>"""
+Password: <input type="password" name="password" required></li>""",
)
# An 'initial' value is *not* used as a fallback if data is not provided. In this
# example, we don't provide a value for 'username', and the form raises a
# validation error rather than using the initial value for 'username'.
- p = UserRegistration({'password': 'secret'})
- self.assertEqual(p.errors['username'], ['This field is required.'])
+ p = UserRegistration({"password": "secret"})
+ self.assertEqual(p.errors["username"], ["This field is required."])
self.assertFalse(p.is_valid())
def test_dynamic_initial_data(self):
@@ -1889,61 +2176,66 @@ Password: <input type="password" name="password" required></li>"""
password = CharField(widget=PasswordInput)
# Here, we're not submitting any data, so the initial value will be displayed.)
- p = UserRegistration(initial={'username': 'django'}, auto_id=False)
+ p = UserRegistration(initial={"username": "django"}, auto_id=False)
self.assertHTMLEqual(
p.as_ul(),
"""<li>Username: <input type="text" name="username" value="django" maxlength="10" required></li>
-<li>Password: <input type="password" name="password" required></li>"""
+<li>Password: <input type="password" name="password" required></li>""",
)
- p = UserRegistration(initial={'username': 'stephane'}, auto_id=False)
+ p = UserRegistration(initial={"username": "stephane"}, auto_id=False)
self.assertHTMLEqual(
p.as_ul(),
"""<li>Username: <input type="text" name="username" value="stephane" maxlength="10" required></li>
-<li>Password: <input type="password" name="password" required></li>"""
+<li>Password: <input type="password" name="password" required></li>""",
)
# The 'initial' parameter is meaningless if you pass data.
- p = UserRegistration({}, initial={'username': 'django'}, auto_id=False)
+ p = UserRegistration({}, initial={"username": "django"}, auto_id=False)
self.assertHTMLEqual(
p.as_ul(),
"""<li><ul class="errorlist"><li>This field is required.</li></ul>
Username: <input type="text" name="username" maxlength="10" required></li>
<li><ul class="errorlist"><li>This field is required.</li></ul>
-Password: <input type="password" name="password" required></li>"""
+Password: <input type="password" name="password" required></li>""",
+ )
+ p = UserRegistration(
+ {"username": ""}, initial={"username": "django"}, auto_id=False
)
- p = UserRegistration({'username': ''}, initial={'username': 'django'}, auto_id=False)
self.assertHTMLEqual(
p.as_ul(),
"""<li><ul class="errorlist"><li>This field is required.</li></ul>
Username: <input type="text" name="username" maxlength="10" required></li>
<li><ul class="errorlist"><li>This field is required.</li></ul>
-Password: <input type="password" name="password" required></li>"""
+Password: <input type="password" name="password" required></li>""",
+ )
+ p = UserRegistration(
+ {"username": "foo"}, initial={"username": "django"}, auto_id=False
)
- p = UserRegistration({'username': 'foo'}, initial={'username': 'django'}, auto_id=False)
self.assertHTMLEqual(
- p.as_ul(), """<li>Username: <input type="text" name="username" value="foo" maxlength="10" required></li>
+ p.as_ul(),
+ """<li>Username: <input type="text" name="username" value="foo" maxlength="10" required></li>
<li><ul class="errorlist"><li>This field is required.</li></ul>
-Password: <input type="password" name="password" required></li>"""
+Password: <input type="password" name="password" required></li>""",
)
# A dynamic 'initial' value is *not* used as a fallback if data is not provided.
# In this example, we don't provide a value for 'username', and the form raises a
# validation error rather than using the initial value for 'username'.
- p = UserRegistration({'password': 'secret'}, initial={'username': 'django'})
- self.assertEqual(p.errors['username'], ['This field is required.'])
+ p = UserRegistration({"password": "secret"}, initial={"username": "django"})
+ self.assertEqual(p.errors["username"], ["This field is required."])
self.assertFalse(p.is_valid())
# If a Form defines 'initial' *and* 'initial' is passed as a parameter to Form(),
# then the latter will get precedence.
class UserRegistration(Form):
- username = CharField(max_length=10, initial='django')
+ username = CharField(max_length=10, initial="django")
password = CharField(widget=PasswordInput)
- p = UserRegistration(initial={'username': 'babik'}, auto_id=False)
+ p = UserRegistration(initial={"username": "babik"}, auto_id=False)
self.assertHTMLEqual(
p.as_ul(),
"""<li>Username: <input type="text" name="username" value="babik" maxlength="10" required></li>
-<li>Password: <input type="password" name="password" required></li>"""
+<li>Password: <input type="password" name="password" required></li>""",
)
def test_callable_initial_data(self):
@@ -1952,23 +2244,28 @@ Password: <input type="password" name="password" required></li>"""
class UserRegistration(Form):
username = CharField(max_length=10)
password = CharField(widget=PasswordInput)
- options = MultipleChoiceField(choices=[('f', 'foo'), ('b', 'bar'), ('w', 'whiz')])
+ options = MultipleChoiceField(
+ choices=[("f", "foo"), ("b", "bar"), ("w", "whiz")]
+ )
# We need to define functions that get called later.)
def initial_django():
- return 'django'
+ return "django"
def initial_stephane():
- return 'stephane'
+ return "stephane"
def initial_options():
- return ['f', 'b']
+ return ["f", "b"]
def initial_other_options():
- return ['b', 'w']
+ return ["b", "w"]
# Here, we're not submitting any data, so the initial value will be displayed.)
- p = UserRegistration(initial={'username': initial_django, 'options': initial_options}, auto_id=False)
+ p = UserRegistration(
+ initial={"username": initial_django, "options": initial_options},
+ auto_id=False,
+ )
self.assertHTMLEqual(
p.as_ul(),
"""<li>Username: <input type="text" name="username" value="django" maxlength="10" required></li>
@@ -1977,11 +2274,15 @@ Password: <input type="password" name="password" required></li>"""
<option value="f" selected>foo</option>
<option value="b" selected>bar</option>
<option value="w">whiz</option>
-</select></li>"""
+</select></li>""",
)
# The 'initial' parameter is meaningless if you pass data.
- p = UserRegistration({}, initial={'username': initial_django, 'options': initial_options}, auto_id=False)
+ p = UserRegistration(
+ {},
+ initial={"username": initial_django, "options": initial_options},
+ auto_id=False,
+ )
self.assertHTMLEqual(
p.as_ul(),
"""<li><ul class="errorlist"><li>This field is required.</li></ul>
@@ -1993,9 +2294,11 @@ Options: <select multiple name="options" required>
<option value="f">foo</option>
<option value="b">bar</option>
<option value="w">whiz</option>
-</select></li>"""
+</select></li>""",
+ )
+ p = UserRegistration(
+ {"username": ""}, initial={"username": initial_django}, auto_id=False
)
- p = UserRegistration({'username': ''}, initial={'username': initial_django}, auto_id=False)
self.assertHTMLEqual(
p.as_ul(),
"""<li><ul class="errorlist"><li>This field is required.</li></ul>
@@ -2007,10 +2310,12 @@ Options: <select multiple name="options" required>
<option value="f">foo</option>
<option value="b">bar</option>
<option value="w">whiz</option>
-</select></li>"""
+</select></li>""",
)
p = UserRegistration(
- {'username': 'foo', 'options': ['f', 'b']}, initial={'username': initial_django}, auto_id=False
+ {"username": "foo", "options": ["f", "b"]},
+ initial={"username": initial_django},
+ auto_id=False,
)
self.assertHTMLEqual(
p.as_ul(),
@@ -2021,14 +2326,17 @@ Password: <input type="password" name="password" required></li>
<option value="f" selected>foo</option>
<option value="b" selected>bar</option>
<option value="w">whiz</option>
-</select></li>"""
+</select></li>""",
)
# A callable 'initial' value is *not* used as a fallback if data is not provided.
# In this example, we don't provide a value for 'username', and the form raises a
# validation error rather than using the initial value for 'username'.
- p = UserRegistration({'password': 'secret'}, initial={'username': initial_django, 'options': initial_options})
- self.assertEqual(p.errors['username'], ['This field is required.'])
+ p = UserRegistration(
+ {"password": "secret"},
+ initial={"username": initial_django, "options": initial_options},
+ )
+ self.assertEqual(p.errors["username"], ["This field is required."])
self.assertFalse(p.is_valid())
# If a Form defines 'initial' *and* 'initial' is passed as a parameter to Form(),
@@ -2037,7 +2345,7 @@ Password: <input type="password" name="password" required></li>
username = CharField(max_length=10, initial=initial_django)
password = CharField(widget=PasswordInput)
options = MultipleChoiceField(
- choices=[('f', 'foo'), ('b', 'bar'), ('w', 'whiz')],
+ choices=[("f", "foo"), ("b", "bar"), ("w", "whiz")],
initial=initial_other_options,
)
@@ -2050,9 +2358,12 @@ Password: <input type="password" name="password" required></li>
<option value="f">foo</option>
<option value="b" selected>bar</option>
<option value="w" selected>whiz</option>
-</select></li>"""
+</select></li>""",
+ )
+ p = UserRegistration(
+ initial={"username": initial_stephane, "options": initial_options},
+ auto_id=False,
)
- p = UserRegistration(initial={'username': initial_stephane, 'options': initial_options}, auto_id=False)
self.assertHTMLEqual(
p.as_ul(),
"""<li>Username: <input type="text" name="username" value="stephane" maxlength="10" required></li>
@@ -2061,31 +2372,31 @@ Password: <input type="password" name="password" required></li>
<option value="f" selected>foo</option>
<option value="b" selected>bar</option>
<option value="w">whiz</option>
-</select></li>"""
+</select></li>""",
)
def test_get_initial_for_field(self):
now = datetime.datetime(2006, 10, 25, 14, 30, 45, 123456)
class PersonForm(Form):
- first_name = CharField(initial='John')
- last_name = CharField(initial='Doe')
+ first_name = CharField(initial="John")
+ last_name = CharField(initial="Doe")
age = IntegerField()
- occupation = CharField(initial=lambda: 'Unknown')
+ occupation = CharField(initial=lambda: "Unknown")
dt_fixed = DateTimeField(initial=now)
dt_callable = DateTimeField(initial=lambda: now)
- form = PersonForm(initial={'first_name': 'Jane'})
+ form = PersonForm(initial={"first_name": "Jane"})
cases = [
- ('age', None),
- ('last_name', 'Doe'),
+ ("age", None),
+ ("last_name", "Doe"),
# Form.initial overrides Field.initial.
- ('first_name', 'Jane'),
+ ("first_name", "Jane"),
# Callables are evaluated.
- ('occupation', 'Unknown'),
+ ("occupation", "Unknown"),
# Microseconds are removed from datetimes.
- ('dt_fixed', datetime.datetime(2006, 10, 25, 14, 30, 45)),
- ('dt_callable', datetime.datetime(2006, 10, 25, 14, 30, 45)),
+ ("dt_fixed", datetime.datetime(2006, 10, 25, 14, 30, 45)),
+ ("dt_callable", datetime.datetime(2006, 10, 25, 14, 30, 45)),
]
for field_name, expected in cases:
with self.subTest(field_name=field_name):
@@ -2095,72 +2406,79 @@ Password: <input type="password" name="password" required></li>
def test_changed_data(self):
class Person(Form):
- first_name = CharField(initial='Hans')
- last_name = CharField(initial='Greatel')
+ first_name = CharField(initial="Hans")
+ last_name = CharField(initial="Greatel")
birthday = DateField(initial=datetime.date(1974, 8, 16))
- p = Person(data={'first_name': 'Hans', 'last_name': 'Scrmbl', 'birthday': '1974-08-16'})
+ p = Person(
+ data={"first_name": "Hans", "last_name": "Scrmbl", "birthday": "1974-08-16"}
+ )
self.assertTrue(p.is_valid())
- self.assertNotIn('first_name', p.changed_data)
- self.assertIn('last_name', p.changed_data)
- self.assertNotIn('birthday', p.changed_data)
+ self.assertNotIn("first_name", p.changed_data)
+ self.assertIn("last_name", p.changed_data)
+ self.assertNotIn("birthday", p.changed_data)
# A field raising ValidationError is always in changed_data
class PedanticField(forms.Field):
def to_python(self, value):
- raise ValidationError('Whatever')
+ raise ValidationError("Whatever")
class Person2(Person):
- pedantic = PedanticField(initial='whatever', show_hidden_initial=True)
+ pedantic = PedanticField(initial="whatever", show_hidden_initial=True)
- p = Person2(data={
- 'first_name': 'Hans', 'last_name': 'Scrmbl', 'birthday': '1974-08-16',
- 'initial-pedantic': 'whatever',
- })
+ p = Person2(
+ data={
+ "first_name": "Hans",
+ "last_name": "Scrmbl",
+ "birthday": "1974-08-16",
+ "initial-pedantic": "whatever",
+ }
+ )
self.assertFalse(p.is_valid())
- self.assertIn('pedantic', p.changed_data)
+ self.assertIn("pedantic", p.changed_data)
def test_boundfield_values(self):
# It's possible to get to the value which would be used for rendering
# the widget for a field by using the BoundField's value method.
class UserRegistration(Form):
- username = CharField(max_length=10, initial='djangonaut')
+ username = CharField(max_length=10, initial="djangonaut")
password = CharField(widget=PasswordInput)
unbound = UserRegistration()
- bound = UserRegistration({'password': 'foo'})
- self.assertIsNone(bound['username'].value())
- self.assertEqual(unbound['username'].value(), 'djangonaut')
- self.assertEqual(bound['password'].value(), 'foo')
- self.assertIsNone(unbound['password'].value())
+ bound = UserRegistration({"password": "foo"})
+ self.assertIsNone(bound["username"].value())
+ self.assertEqual(unbound["username"].value(), "djangonaut")
+ self.assertEqual(bound["password"].value(), "foo")
+ self.assertIsNone(unbound["password"].value())
def test_boundfield_initial_called_once(self):
"""
Multiple calls to BoundField().value() in an unbound form should return
the same result each time (#24391).
"""
+
class MyForm(Form):
name = CharField(max_length=10, initial=uuid.uuid4)
form = MyForm()
- name = form['name']
+ name = form["name"]
self.assertEqual(name.value(), name.value())
# BoundField is also cached
- self.assertIs(form['name'], name)
+ self.assertIs(form["name"], name)
def test_boundfield_value_disabled_callable_initial(self):
class PersonForm(Form):
- name = CharField(initial=lambda: 'John Doe', disabled=True)
+ name = CharField(initial=lambda: "John Doe", disabled=True)
# Without form data.
form = PersonForm()
- self.assertEqual(form['name'].value(), 'John Doe')
+ self.assertEqual(form["name"].value(), "John Doe")
# With form data. As the field is disabled, the value should not be
# affected by the form data.
form = PersonForm({})
- self.assertEqual(form['name'].value(), 'John Doe')
+ self.assertEqual(form["name"].value(), "John Doe")
def test_custom_boundfield(self):
class CustomField(CharField):
@@ -2171,7 +2489,7 @@ Password: <input type="password" name="password" required></li>
name = CustomField()
f = SampleForm()
- self.assertEqual(f['name'], (f, 'name'))
+ self.assertEqual(f["name"], (f, "name"))
def test_initial_datetime_values(self):
now = datetime.datetime.now()
@@ -2199,18 +2517,22 @@ Password: <input type="password" name="password" required></li>
auto_time_only = TimeField(initial=delayed_now_time)
supports_microseconds = DateTimeField(initial=delayed_now, widget=TextInput)
hi_default_microsec = DateTimeField(initial=delayed_now, widget=HiddenInput)
- hi_without_microsec = DateTimeField(initial=delayed_now, widget=HiddenInputWithoutMicrosec)
- ti_without_microsec = DateTimeField(initial=delayed_now, widget=TextInputWithoutMicrosec)
+ hi_without_microsec = DateTimeField(
+ initial=delayed_now, widget=HiddenInputWithoutMicrosec
+ )
+ ti_without_microsec = DateTimeField(
+ initial=delayed_now, widget=TextInputWithoutMicrosec
+ )
unbound = DateTimeForm()
cases = [
- ('fixed', now_no_ms),
- ('auto_timestamp', now_no_ms),
- ('auto_time_only', now_no_ms.time()),
- ('supports_microseconds', now),
- ('hi_default_microsec', now),
- ('hi_without_microsec', now_no_ms),
- ('ti_without_microsec', now_no_ms),
+ ("fixed", now_no_ms),
+ ("auto_timestamp", now_no_ms),
+ ("auto_time_only", now_no_ms.time()),
+ ("supports_microseconds", now),
+ ("hi_default_microsec", now),
+ ("hi_without_microsec", now_no_ms),
+ ("ti_without_microsec", now_no_ms),
]
for field_name, expected in cases:
with self.subTest(field_name=field_name):
@@ -2229,7 +2551,12 @@ Password: <input type="password" name="password" required></li>
def now(self):
self.elapsed_seconds += 1
return datetime.datetime(
- 2006, 10, 25, 14, 30, 45 + self.elapsed_seconds,
+ 2006,
+ 10,
+ 25,
+ 14,
+ 30,
+ 45 + self.elapsed_seconds,
microseconds,
)
@@ -2244,12 +2571,16 @@ Password: <input type="password" name="password" required></li>
removes microseconds.
"""
form = self.get_datetime_form_with_callable_initial(
- disabled=True, microseconds=123456,
+ disabled=True,
+ microseconds=123456,
)
self.assertEqual(form.errors, {})
- self.assertEqual(form.cleaned_data, {
- 'dt': datetime.datetime(2006, 10, 25, 14, 30, 46),
- })
+ self.assertEqual(
+ form.cleaned_data,
+ {
+ "dt": datetime.datetime(2006, 10, 25, 14, 30, 46),
+ },
+ )
def test_datetime_clean_disabled_callable_initial_bound_field(self):
"""
@@ -2258,23 +2589,28 @@ Password: <input type="password" name="password" required></li>
"""
form = self.get_datetime_form_with_callable_initial(disabled=True)
self.assertEqual(form.errors, {})
- cleaned = form.cleaned_data['dt']
+ cleaned = form.cleaned_data["dt"]
self.assertEqual(cleaned, datetime.datetime(2006, 10, 25, 14, 30, 46))
- bf = form['dt']
+ bf = form["dt"]
self.assertEqual(cleaned, bf.initial)
def test_datetime_changed_data_callable_with_microseconds(self):
class DateTimeForm(forms.Form):
- dt = DateTimeField(initial=lambda: datetime.datetime(2006, 10, 25, 14, 30, 45, 123456), disabled=True)
+ dt = DateTimeField(
+ initial=lambda: datetime.datetime(2006, 10, 25, 14, 30, 45, 123456),
+ disabled=True,
+ )
- form = DateTimeForm({'dt': '2006-10-25 14:30:45'})
+ form = DateTimeForm({"dt": "2006-10-25 14:30:45"})
self.assertEqual(form.changed_data, [])
def test_help_text(self):
# You can specify descriptive text for a field by using the 'help_text' argument)
class UserRegistration(Form):
- username = CharField(max_length=10, help_text='e.g., user@example.com')
- password = CharField(widget=PasswordInput, help_text='Wählen Sie mit Bedacht.')
+ username = CharField(max_length=10, help_text="e.g., user@example.com")
+ password = CharField(
+ widget=PasswordInput, help_text="Wählen Sie mit Bedacht."
+ )
p = UserRegistration(auto_id=False)
self.assertHTMLEqual(
@@ -2282,40 +2618,42 @@ Password: <input type="password" name="password" required></li>
"""<li>Username: <input type="text" name="username" maxlength="10" required>
<span class="helptext">e.g., user@example.com</span></li>
<li>Password: <input type="password" name="password" required>
-<span class="helptext">Wählen Sie mit Bedacht.</span></li>"""
+<span class="helptext">Wählen Sie mit Bedacht.</span></li>""",
)
self.assertHTMLEqual(
p.as_p(),
"""<p>Username: <input type="text" name="username" maxlength="10" required>
<span class="helptext">e.g., user@example.com</span></p>
<p>Password: <input type="password" name="password" required>
-<span class="helptext">Wählen Sie mit Bedacht.</span></p>"""
+<span class="helptext">Wählen Sie mit Bedacht.</span></p>""",
)
self.assertHTMLEqual(
p.as_table(),
"""<tr><th>Username:</th><td><input type="text" name="username" maxlength="10" required><br>
<span class="helptext">e.g., user@example.com</span></td></tr>
<tr><th>Password:</th><td><input type="password" name="password" required><br>
-<span class="helptext">Wählen Sie mit Bedacht.</span></td></tr>"""
+<span class="helptext">Wählen Sie mit Bedacht.</span></td></tr>""",
)
# The help text is displayed whether or not data is provided for the form.
- p = UserRegistration({'username': 'foo'}, auto_id=False)
+ p = UserRegistration({"username": "foo"}, auto_id=False)
self.assertHTMLEqual(
p.as_ul(),
"""<li>Username: <input type="text" name="username" value="foo" maxlength="10" required>
<span class="helptext">e.g., user@example.com</span></li>
<li><ul class="errorlist"><li>This field is required.</li></ul>
Password: <input type="password" name="password" required>
-<span class="helptext">Wählen Sie mit Bedacht.</span></li>"""
+<span class="helptext">Wählen Sie mit Bedacht.</span></li>""",
)
# help_text is not displayed for hidden fields. It can be used for documentation
# purposes, though.
class UserRegistration(Form):
- username = CharField(max_length=10, help_text='e.g., user@example.com')
+ username = CharField(max_length=10, help_text="e.g., user@example.com")
password = CharField(widget=PasswordInput)
- next = CharField(widget=HiddenInput, initial='/', help_text='Redirect destination')
+ next = CharField(
+ widget=HiddenInput, initial="/", help_text="Redirect destination"
+ )
p = UserRegistration(auto_id=False)
self.assertHTMLEqual(
@@ -2323,16 +2661,17 @@ Password: <input type="password" name="password" required>
"""<li>Username: <input type="text" name="username" maxlength="10" required>
<span class="helptext">e.g., user@example.com</span></li>
<li>Password: <input type="password" name="password" required>
-<input type="hidden" name="next" value="/"></li>"""
+<input type="hidden" name="next" value="/"></li>""",
)
def test_help_text_html_safe(self):
"""help_text should not be escaped."""
+
class UserRegistration(Form):
- username = CharField(max_length=10, help_text='e.g., user@example.com')
+ username = CharField(max_length=10, help_text="e.g., user@example.com")
password = CharField(
widget=PasswordInput,
- help_text='Help text is <strong>escaped</strong>.',
+ help_text="Help text is <strong>escaped</strong>.",
)
p = UserRegistration(auto_id=False)
@@ -2341,24 +2680,24 @@ Password: <input type="password" name="password" required>
'<li>Username: <input type="text" name="username" maxlength="10" required>'
'<span class="helptext">e.g., user@example.com</span></li>'
'<li>Password: <input type="password" name="password" required>'
- '<span class="helptext">Help text is <strong>escaped</strong>.</span></li>'
+ '<span class="helptext">Help text is <strong>escaped</strong>.</span></li>',
)
self.assertHTMLEqual(
p.as_p(),
'<p>Username: <input type="text" name="username" maxlength="10" required>'
'<span class="helptext">e.g., user@example.com</span></p>'
'<p>Password: <input type="password" name="password" required>'
- '<span class="helptext">Help text is <strong>escaped</strong>.</span></p>'
+ '<span class="helptext">Help text is <strong>escaped</strong>.</span></p>',
)
self.assertHTMLEqual(
p.as_table(),
- '<tr><th>Username:</th><td>'
+ "<tr><th>Username:</th><td>"
'<input type="text" name="username" maxlength="10" required><br>'
'<span class="helptext">e.g., user@example.com</span></td></tr>'
- '<tr><th>Password:</th><td>'
+ "<tr><th>Password:</th><td>"
'<input type="password" name="password" required><br>'
'<span class="helptext">Help text is <strong>escaped</strong>.</span>'
- '</td></tr>'
+ "</td></tr>",
)
def test_subclassing_forms(self):
@@ -2378,7 +2717,7 @@ Password: <input type="password" name="password" required>
p.as_ul(),
"""<li>First name: <input type="text" name="first_name" required></li>
<li>Last name: <input type="text" name="last_name" required></li>
-<li>Birthday: <input type="text" name="birthday" required></li>"""
+<li>Birthday: <input type="text" name="birthday" required></li>""",
)
m = Musician(auto_id=False)
self.assertHTMLEqual(
@@ -2386,7 +2725,7 @@ Password: <input type="password" name="password" required>
"""<li>First name: <input type="text" name="first_name" required></li>
<li>Last name: <input type="text" name="last_name" required></li>
<li>Birthday: <input type="text" name="birthday" required></li>
-<li>Instrument: <input type="text" name="instrument" required></li>"""
+<li>Instrument: <input type="text" name="instrument" required></li>""",
)
# Yes, you can subclass multiple forms. The fields are added in the order in
@@ -2403,11 +2742,14 @@ Password: <input type="password" name="password" required>
haircut_type = CharField()
b = Beatle(auto_id=False)
- self.assertHTMLEqual(b.as_ul(), """<li>Instrument: <input type="text" name="instrument" required></li>
+ self.assertHTMLEqual(
+ b.as_ul(),
+ """<li>Instrument: <input type="text" name="instrument" required></li>
<li>First name: <input type="text" name="first_name" required></li>
<li>Last name: <input type="text" name="last_name" required></li>
<li>Birthday: <input type="text" name="birthday" required></li>
-<li>Haircut type: <input type="text" name="haircut_type" required></li>""")
+<li>Haircut type: <input type="text" name="haircut_type" required></li>""",
+ )
def test_forms_with_prefixes(self):
# Sometimes it's necessary to have multiple forms display on the same HTML page,
@@ -2423,11 +2765,11 @@ Password: <input type="password" name="password" required>
birthday = DateField()
data = {
- 'person1-first_name': 'John',
- 'person1-last_name': 'Lennon',
- 'person1-birthday': '1940-10-9'
+ "person1-first_name": "John",
+ "person1-last_name": "Lennon",
+ "person1-birthday": "1940-10-9",
}
- p = Person(data, prefix='person1')
+ p = Person(data, prefix="person1")
self.assertHTMLEqual(
p.as_ul(),
"""<li><label for="id_person1-first_name">First name:</label>
@@ -2435,74 +2777,70 @@ Password: <input type="password" name="password" required>
<li><label for="id_person1-last_name">Last name:</label>
<input type="text" name="person1-last_name" value="Lennon" id="id_person1-last_name" required></li>
<li><label for="id_person1-birthday">Birthday:</label>
-<input type="text" name="person1-birthday" value="1940-10-9" id="id_person1-birthday" required></li>"""
+<input type="text" name="person1-birthday" value="1940-10-9" id="id_person1-birthday" required></li>""",
)
self.assertHTMLEqual(
- str(p['first_name']),
- '<input type="text" name="person1-first_name" value="John" id="id_person1-first_name" required>'
+ str(p["first_name"]),
+ '<input type="text" name="person1-first_name" value="John" id="id_person1-first_name" required>',
)
self.assertHTMLEqual(
- str(p['last_name']),
- '<input type="text" name="person1-last_name" value="Lennon" id="id_person1-last_name" required>'
+ str(p["last_name"]),
+ '<input type="text" name="person1-last_name" value="Lennon" id="id_person1-last_name" required>',
)
self.assertHTMLEqual(
- str(p['birthday']),
- '<input type="text" name="person1-birthday" value="1940-10-9" id="id_person1-birthday" required>'
+ str(p["birthday"]),
+ '<input type="text" name="person1-birthday" value="1940-10-9" id="id_person1-birthday" required>',
)
self.assertEqual(p.errors, {})
self.assertTrue(p.is_valid())
- self.assertEqual(p.cleaned_data['first_name'], 'John')
- self.assertEqual(p.cleaned_data['last_name'], 'Lennon')
- self.assertEqual(p.cleaned_data['birthday'], datetime.date(1940, 10, 9))
+ self.assertEqual(p.cleaned_data["first_name"], "John")
+ self.assertEqual(p.cleaned_data["last_name"], "Lennon")
+ self.assertEqual(p.cleaned_data["birthday"], datetime.date(1940, 10, 9))
# Let's try submitting some bad data to make sure form.errors and field.errors
# work as expected.
data = {
- 'person1-first_name': '',
- 'person1-last_name': '',
- 'person1-birthday': ''
+ "person1-first_name": "",
+ "person1-last_name": "",
+ "person1-birthday": "",
}
- p = Person(data, prefix='person1')
- self.assertEqual(p.errors['first_name'], ['This field is required.'])
- self.assertEqual(p.errors['last_name'], ['This field is required.'])
- self.assertEqual(p.errors['birthday'], ['This field is required.'])
- self.assertEqual(p['first_name'].errors, ['This field is required.'])
+ p = Person(data, prefix="person1")
+ self.assertEqual(p.errors["first_name"], ["This field is required."])
+ self.assertEqual(p.errors["last_name"], ["This field is required."])
+ self.assertEqual(p.errors["birthday"], ["This field is required."])
+ self.assertEqual(p["first_name"].errors, ["This field is required."])
# Accessing a nonexistent field.
with self.assertRaises(KeyError):
- p['person1-first_name'].errors
+ p["person1-first_name"].errors
# In this example, the data doesn't have a prefix, but the form requires it, so
# the form doesn't "see" the fields.
- data = {
- 'first_name': 'John',
- 'last_name': 'Lennon',
- 'birthday': '1940-10-9'
- }
- p = Person(data, prefix='person1')
- self.assertEqual(p.errors['first_name'], ['This field is required.'])
- self.assertEqual(p.errors['last_name'], ['This field is required.'])
- self.assertEqual(p.errors['birthday'], ['This field is required.'])
+ data = {"first_name": "John", "last_name": "Lennon", "birthday": "1940-10-9"}
+ p = Person(data, prefix="person1")
+ self.assertEqual(p.errors["first_name"], ["This field is required."])
+ self.assertEqual(p.errors["last_name"], ["This field is required."])
+ self.assertEqual(p.errors["birthday"], ["This field is required."])
# With prefixes, a single data dictionary can hold data for multiple instances
# of the same form.
data = {
- 'person1-first_name': 'John',
- 'person1-last_name': 'Lennon',
- 'person1-birthday': '1940-10-9',
- 'person2-first_name': 'Jim',
- 'person2-last_name': 'Morrison',
- 'person2-birthday': '1943-12-8'
+ "person1-first_name": "John",
+ "person1-last_name": "Lennon",
+ "person1-birthday": "1940-10-9",
+ "person2-first_name": "Jim",
+ "person2-last_name": "Morrison",
+ "person2-birthday": "1943-12-8",
}
- p1 = Person(data, prefix='person1')
+ p1 = Person(data, prefix="person1")
self.assertTrue(p1.is_valid())
- self.assertEqual(p1.cleaned_data['first_name'], 'John')
- self.assertEqual(p1.cleaned_data['last_name'], 'Lennon')
- self.assertEqual(p1.cleaned_data['birthday'], datetime.date(1940, 10, 9))
- p2 = Person(data, prefix='person2')
+ self.assertEqual(p1.cleaned_data["first_name"], "John")
+ self.assertEqual(p1.cleaned_data["last_name"], "Lennon")
+ self.assertEqual(p1.cleaned_data["birthday"], datetime.date(1940, 10, 9))
+ p2 = Person(data, prefix="person2")
self.assertTrue(p2.is_valid())
- self.assertEqual(p2.cleaned_data['first_name'], 'Jim')
- self.assertEqual(p2.cleaned_data['last_name'], 'Morrison')
- self.assertEqual(p2.cleaned_data['birthday'], datetime.date(1943, 12, 8))
+ self.assertEqual(p2.cleaned_data["first_name"], "Jim")
+ self.assertEqual(p2.cleaned_data["last_name"], "Morrison")
+ self.assertEqual(p2.cleaned_data["birthday"], datetime.date(1943, 12, 8))
# By default, forms append a hyphen between the prefix and the field name, but a
# form can alter that behavior by implementing the add_prefix() method. This
@@ -2514,9 +2852,13 @@ Password: <input type="password" name="password" required>
birthday = DateField()
def add_prefix(self, field_name):
- return '%s-prefix-%s' % (self.prefix, field_name) if self.prefix else field_name
+ return (
+ "%s-prefix-%s" % (self.prefix, field_name)
+ if self.prefix
+ else field_name
+ )
- p = Person(prefix='foo')
+ p = Person(prefix="foo")
self.assertHTMLEqual(
p.as_ul(),
"""<li><label for="id_foo-prefix-first_name">First name:</label>
@@ -2524,30 +2866,30 @@ Password: <input type="password" name="password" required>
<li><label for="id_foo-prefix-last_name">Last name:</label>
<input type="text" name="foo-prefix-last_name" id="id_foo-prefix-last_name" required></li>
<li><label for="id_foo-prefix-birthday">Birthday:</label>
-<input type="text" name="foo-prefix-birthday" id="id_foo-prefix-birthday" required></li>"""
+<input type="text" name="foo-prefix-birthday" id="id_foo-prefix-birthday" required></li>""",
)
data = {
- 'foo-prefix-first_name': 'John',
- 'foo-prefix-last_name': 'Lennon',
- 'foo-prefix-birthday': '1940-10-9'
+ "foo-prefix-first_name": "John",
+ "foo-prefix-last_name": "Lennon",
+ "foo-prefix-birthday": "1940-10-9",
}
- p = Person(data, prefix='foo')
+ p = Person(data, prefix="foo")
self.assertTrue(p.is_valid())
- self.assertEqual(p.cleaned_data['first_name'], 'John')
- self.assertEqual(p.cleaned_data['last_name'], 'Lennon')
- self.assertEqual(p.cleaned_data['birthday'], datetime.date(1940, 10, 9))
+ self.assertEqual(p.cleaned_data["first_name"], "John")
+ self.assertEqual(p.cleaned_data["last_name"], "Lennon")
+ self.assertEqual(p.cleaned_data["birthday"], datetime.date(1940, 10, 9))
def test_class_prefix(self):
# Prefix can be also specified at the class level.
class Person(Form):
first_name = CharField()
- prefix = 'foo'
+ prefix = "foo"
p = Person()
- self.assertEqual(p.prefix, 'foo')
+ self.assertEqual(p.prefix, "foo")
- p = Person(prefix='bar')
- self.assertEqual(p.prefix, 'bar')
+ p = Person(prefix="bar")
+ self.assertEqual(p.prefix, "bar")
def test_forms_with_null_boolean(self):
# NullBooleanField is a bit of a special case because its presentation (widget)
@@ -2556,60 +2898,87 @@ Password: <input type="password" name="password" required>
name = CharField()
is_cool = NullBooleanField()
- p = Person({'name': 'Joe'}, auto_id=False)
- self.assertHTMLEqual(str(p['is_cool']), """<select name="is_cool">
+ p = Person({"name": "Joe"}, auto_id=False)
+ self.assertHTMLEqual(
+ str(p["is_cool"]),
+ """<select name="is_cool">
<option value="unknown" selected>Unknown</option>
<option value="true">Yes</option>
<option value="false">No</option>
-</select>""")
- p = Person({'name': 'Joe', 'is_cool': '1'}, auto_id=False)
- self.assertHTMLEqual(str(p['is_cool']), """<select name="is_cool">
+</select>""",
+ )
+ p = Person({"name": "Joe", "is_cool": "1"}, auto_id=False)
+ self.assertHTMLEqual(
+ str(p["is_cool"]),
+ """<select name="is_cool">
<option value="unknown" selected>Unknown</option>
<option value="true">Yes</option>
<option value="false">No</option>
-</select>""")
- p = Person({'name': 'Joe', 'is_cool': '2'}, auto_id=False)
- self.assertHTMLEqual(str(p['is_cool']), """<select name="is_cool">
+</select>""",
+ )
+ p = Person({"name": "Joe", "is_cool": "2"}, auto_id=False)
+ self.assertHTMLEqual(
+ str(p["is_cool"]),
+ """<select name="is_cool">
<option value="unknown">Unknown</option>
<option value="true" selected>Yes</option>
<option value="false">No</option>
-</select>""")
- p = Person({'name': 'Joe', 'is_cool': '3'}, auto_id=False)
- self.assertHTMLEqual(str(p['is_cool']), """<select name="is_cool">
+</select>""",
+ )
+ p = Person({"name": "Joe", "is_cool": "3"}, auto_id=False)
+ self.assertHTMLEqual(
+ str(p["is_cool"]),
+ """<select name="is_cool">
<option value="unknown">Unknown</option>
<option value="true">Yes</option>
<option value="false" selected>No</option>
-</select>""")
- p = Person({'name': 'Joe', 'is_cool': True}, auto_id=False)
- self.assertHTMLEqual(str(p['is_cool']), """<select name="is_cool">
+</select>""",
+ )
+ p = Person({"name": "Joe", "is_cool": True}, auto_id=False)
+ self.assertHTMLEqual(
+ str(p["is_cool"]),
+ """<select name="is_cool">
<option value="unknown">Unknown</option>
<option value="true" selected>Yes</option>
<option value="false">No</option>
-</select>""")
- p = Person({'name': 'Joe', 'is_cool': False}, auto_id=False)
- self.assertHTMLEqual(str(p['is_cool']), """<select name="is_cool">
+</select>""",
+ )
+ p = Person({"name": "Joe", "is_cool": False}, auto_id=False)
+ self.assertHTMLEqual(
+ str(p["is_cool"]),
+ """<select name="is_cool">
<option value="unknown">Unknown</option>
<option value="true">Yes</option>
<option value="false" selected>No</option>
-</select>""")
- p = Person({'name': 'Joe', 'is_cool': 'unknown'}, auto_id=False)
- self.assertHTMLEqual(str(p['is_cool']), """<select name="is_cool">
+</select>""",
+ )
+ p = Person({"name": "Joe", "is_cool": "unknown"}, auto_id=False)
+ self.assertHTMLEqual(
+ str(p["is_cool"]),
+ """<select name="is_cool">
<option value="unknown" selected>Unknown</option>
<option value="true">Yes</option>
<option value="false">No</option>
-</select>""")
- p = Person({'name': 'Joe', 'is_cool': 'true'}, auto_id=False)
- self.assertHTMLEqual(str(p['is_cool']), """<select name="is_cool">
+</select>""",
+ )
+ p = Person({"name": "Joe", "is_cool": "true"}, auto_id=False)
+ self.assertHTMLEqual(
+ str(p["is_cool"]),
+ """<select name="is_cool">
<option value="unknown">Unknown</option>
<option value="true" selected>Yes</option>
<option value="false">No</option>
-</select>""")
- p = Person({'name': 'Joe', 'is_cool': 'false'}, auto_id=False)
- self.assertHTMLEqual(str(p['is_cool']), """<select name="is_cool">
+</select>""",
+ )
+ p = Person({"name": "Joe", "is_cool": "false"}, auto_id=False)
+ self.assertHTMLEqual(
+ str(p["is_cool"]),
+ """<select name="is_cool">
<option value="unknown">Unknown</option>
<option value="true">Yes</option>
<option value="false" selected>No</option>
-</select>""")
+</select>""",
+ )
def test_forms_with_file_fields(self):
# FileFields are a special case because they take their data from the request.FILES,
@@ -2626,37 +2995,47 @@ Password: <input type="password" name="password" required>
f = FileForm(data={}, files={}, auto_id=False)
self.assertHTMLEqual(
f.as_table(),
- '<tr><th>File1:</th><td>'
+ "<tr><th>File1:</th><td>"
'<ul class="errorlist"><li>This field is required.</li></ul>'
- '<input type="file" name="file1" required></td></tr>'
+ '<input type="file" name="file1" required></td></tr>',
)
- f = FileForm(data={}, files={'file1': SimpleUploadedFile('name', b'')}, auto_id=False)
+ f = FileForm(
+ data={}, files={"file1": SimpleUploadedFile("name", b"")}, auto_id=False
+ )
self.assertHTMLEqual(
f.as_table(),
- '<tr><th>File1:</th><td>'
+ "<tr><th>File1:</th><td>"
'<ul class="errorlist"><li>The submitted file is empty.</li></ul>'
- '<input type="file" name="file1" required></td></tr>'
+ '<input type="file" name="file1" required></td></tr>',
)
- f = FileForm(data={}, files={'file1': 'something that is not a file'}, auto_id=False)
+ f = FileForm(
+ data={}, files={"file1": "something that is not a file"}, auto_id=False
+ )
self.assertHTMLEqual(
f.as_table(),
- '<tr><th>File1:</th><td>'
+ "<tr><th>File1:</th><td>"
'<ul class="errorlist"><li>No file was submitted. Check the '
- 'encoding type on the form.</li></ul>'
- '<input type="file" name="file1" required></td></tr>'
+ "encoding type on the form.</li></ul>"
+ '<input type="file" name="file1" required></td></tr>',
)
- f = FileForm(data={}, files={'file1': SimpleUploadedFile('name', b'some content')}, auto_id=False)
+ f = FileForm(
+ data={},
+ files={"file1": SimpleUploadedFile("name", b"some content")},
+ auto_id=False,
+ )
self.assertHTMLEqual(
f.as_table(),
'<tr><th>File1:</th><td><input type="file" name="file1" required></td></tr>',
)
self.assertTrue(f.is_valid())
- file1 = SimpleUploadedFile('我隻氣墊船裝滿晒鱔.txt', 'मेरी मँडराने वाली नाव सर्पमीनों से भरी ह'.encode())
- f = FileForm(data={}, files={'file1': file1}, auto_id=False)
+ file1 = SimpleUploadedFile(
+ "我隻氣墊船裝滿晒鱔.txt", "मेरी मँडराने वाली नाव सर्पमीनों से भरी ह".encode()
+ )
+ f = FileForm(data={}, files={"file1": file1}, auto_id=False)
self.assertHTMLEqual(
f.as_table(),
'<tr><th>File1:</th><td><input type="file" name="file1" required></td></tr>',
@@ -2665,7 +3044,7 @@ Password: <input type="password" name="password" required>
# A required file field with initial data should not contain the
# required HTML attribute. The file input is left blank by the user to
# keep the existing, initial value.
- f = FileForm(initial={'file1': 'resume.txt'}, auto_id=False)
+ f = FileForm(initial={"file1": "resume.txt"}, auto_id=False)
self.assertHTMLEqual(
f.as_table(),
'<tr><th>File1:</th><td><input type="file" name="file1"></td></tr>',
@@ -2673,11 +3052,11 @@ Password: <input type="password" name="password" required>
def test_filefield_initial_callable(self):
class FileForm(forms.Form):
- file1 = forms.FileField(initial=lambda: 'resume.txt')
+ file1 = forms.FileField(initial=lambda: "resume.txt")
f = FileForm({})
self.assertEqual(f.errors, {})
- self.assertEqual(f.cleaned_data['file1'], 'resume.txt')
+ self.assertEqual(f.cleaned_data["file1"], "resume.txt")
def test_filefield_with_fileinput_required(self):
class FileForm(Form):
@@ -2686,13 +3065,13 @@ Password: <input type="password" name="password" required>
f = FileForm(auto_id=False)
self.assertHTMLEqual(
f.as_table(),
- '<tr><th>File1:</th><td>'
+ "<tr><th>File1:</th><td>"
'<input type="file" name="file1" required></td></tr>',
)
# A required file field with initial data doesn't contain the required
# HTML attribute. The file input is left blank by the user to keep the
# existing, initial value.
- f = FileForm(initial={'file1': 'resume.txt'}, auto_id=False)
+ f = FileForm(initial={"file1": "resume.txt"}, auto_id=False)
self.assertHTMLEqual(
f.as_table(),
'<tr><th>File1:</th><td><input type="file" name="file1"></td></tr>',
@@ -2707,10 +3086,16 @@ Password: <input type="password" name="password" required>
name = CharField()
# First let's show what happens id empty_permitted=False (the default):
- data = {'artist': '', 'song': ''}
+ data = {"artist": "", "song": ""}
form = SongForm(data, empty_permitted=False)
self.assertFalse(form.is_valid())
- self.assertEqual(form.errors, {'name': ['This field is required.'], 'artist': ['This field is required.']})
+ self.assertEqual(
+ form.errors,
+ {
+ "name": ["This field is required."],
+ "artist": ["This field is required."],
+ },
+ )
self.assertEqual(form.cleaned_data, {})
# Now let's show what happens when empty_permitted=True and the form is empty.
@@ -2721,16 +3106,16 @@ Password: <input type="password" name="password" required>
# But if we fill in data for one of the fields, the form is no longer empty and
# the whole thing must pass validation.
- data = {'artist': 'The Doors', 'song': ''}
+ data = {"artist": "The Doors", "song": ""}
form = SongForm(data, empty_permitted=False)
self.assertFalse(form.is_valid())
- self.assertEqual(form.errors, {'name': ['This field is required.']})
- self.assertEqual(form.cleaned_data, {'artist': 'The Doors'})
+ self.assertEqual(form.errors, {"name": ["This field is required."]})
+ self.assertEqual(form.cleaned_data, {"artist": "The Doors"})
# If a field is not given in the data then None is returned for its data. Lets
# make sure that when checking for empty_permitted that None is treated
# accordingly.
- data = {'artist': None, 'song': ''}
+ data = {"artist": None, "song": ""}
form = SongForm(data, empty_permitted=True, use_required_attribute=False)
self.assertTrue(form.is_valid())
@@ -2740,14 +3125,19 @@ Password: <input type="password" name="password" required>
amount = FloatField()
qty = IntegerField()
- data = {'amount': '0.0', 'qty': ''}
- form = PriceForm(data, initial={'amount': 0.0}, empty_permitted=True, use_required_attribute=False)
+ data = {"amount": "0.0", "qty": ""}
+ form = PriceForm(
+ data,
+ initial={"amount": 0.0},
+ empty_permitted=True,
+ use_required_attribute=False,
+ )
self.assertTrue(form.is_valid())
def test_empty_permitted_and_use_required_attribute(self):
msg = (
- 'The empty_permitted and use_required_attribute arguments may not '
- 'both be True.'
+ "The empty_permitted and use_required_attribute arguments may not "
+ "both be True."
)
with self.assertRaisesMessage(ValueError, msg):
Person(empty_permitted=True, use_required_attribute=True)
@@ -2759,8 +3149,8 @@ Password: <input type="password" name="password" required>
name = CharField()
form = SongForm()
- self.assertEqual([f.name for f in form.hidden_fields()], ['token'])
- self.assertEqual([f.name for f in form.visible_fields()], ['artist', 'name'])
+ self.assertEqual([f.name for f in form.hidden_fields()], ["token"])
+ self.assertEqual([f.name for f in form.visible_fields()], ["artist", "name"])
def test_hidden_initial_gets_id(self):
class MyForm(Form):
@@ -2770,7 +3160,7 @@ Password: <input type="password" name="password" required>
MyForm().as_table(),
'<tr><th><label for="id_field1">Field1:</label></th>'
'<td><input id="id_field1" type="text" name="field1" maxlength="50" required>'
- '<input type="hidden" name="initial-field1" id="initial-id_field1"></td></tr>'
+ '<input type="hidden" name="initial-field1" id="initial-id_field1"></td></tr>',
)
def test_error_html_required_html_classes(self):
@@ -2781,8 +3171,8 @@ Password: <input type="password" name="password" required>
age = IntegerField()
p = Person({})
- p.error_css_class = 'error'
- p.required_css_class = 'required'
+ p.error_css_class = "error"
+ p.required_css_class = "required"
self.assertHTMLEqual(
p.as_ul(),
@@ -2796,7 +3186,7 @@ Password: <input type="password" name="password" required>
</select></li>
<li><label for="id_email">Email:</label> <input type="email" name="email" id="id_email"></li>
<li class="required error"><ul class="errorlist"><li>This field is required.</li></ul>
-<label class="required" for="id_age">Age:</label> <input type="number" name="age" id="id_age" required></li>"""
+<label class="required" for="id_age">Age:</label> <input type="number" name="age" id="id_age" required></li>""",
)
self.assertHTMLEqual(
@@ -2813,7 +3203,7 @@ Password: <input type="password" name="password" required>
<p><label for="id_email">Email:</label> <input type="email" name="email" id="id_email"></p>
<ul class="errorlist"><li>This field is required.</li></ul>
<p class="required error"><label class="required" for="id_age">Age:</label>
-<input type="number" name="age" id="id_age" required></p>"""
+<input type="number" name="age" id="id_age" required></p>""",
)
self.assertHTMLEqual(
@@ -2832,7 +3222,7 @@ Password: <input type="password" name="password" required>
<input type="email" name="email" id="id_email"></td></tr>
<tr class="required error"><th><label class="required" for="id_age">Age:</label></th>
<td><ul class="errorlist"><li>This field is required.</li></ul>
-<input type="number" name="age" id="id_age" required></td></tr>"""
+<input type="number" name="age" id="id_age" required></td></tr>""",
)
def test_label_has_required_css_class(self):
@@ -2840,28 +3230,34 @@ Password: <input type="password" name="password" required>
required_css_class is added to label_tag() and legend_tag() of required
fields.
"""
+
class SomeForm(Form):
- required_css_class = 'required'
+ required_css_class = "required"
field = CharField(max_length=10)
field2 = IntegerField(required=False)
- f = SomeForm({'field': 'test'})
- self.assertHTMLEqual(f['field'].label_tag(), '<label for="id_field" class="required">Field:</label>')
+ f = SomeForm({"field": "test"})
+ self.assertHTMLEqual(
+ f["field"].label_tag(),
+ '<label for="id_field" class="required">Field:</label>',
+ )
self.assertHTMLEqual(
- f['field'].legend_tag(),
+ f["field"].legend_tag(),
'<legend for="id_field" class="required">Field:</legend>',
)
self.assertHTMLEqual(
- f['field'].label_tag(attrs={'class': 'foo'}),
- '<label for="id_field" class="foo required">Field:</label>'
+ f["field"].label_tag(attrs={"class": "foo"}),
+ '<label for="id_field" class="foo required">Field:</label>',
+ )
+ self.assertHTMLEqual(
+ f["field"].legend_tag(attrs={"class": "foo"}),
+ '<legend for="id_field" class="foo required">Field:</legend>',
)
self.assertHTMLEqual(
- f['field'].legend_tag(attrs={'class': 'foo'}),
- '<legend for="id_field" class="foo required">Field:</legend>'
+ f["field2"].label_tag(), '<label for="id_field2">Field2:</label>'
)
- self.assertHTMLEqual(f['field2'].label_tag(), '<label for="id_field2">Field2:</label>')
self.assertHTMLEqual(
- f['field2'].legend_tag(),
+ f["field2"].legend_tag(),
'<legend for="id_field2">Field2:</legend>',
)
@@ -2873,54 +3269,58 @@ Password: <input type="password" name="password" required>
self.assertHTMLEqual(
form.as_ul(),
'<input type="hidden" name="happened_at_0" id="id_happened_at_0">'
- '<input type="hidden" name="happened_at_1" id="id_happened_at_1">'
+ '<input type="hidden" name="happened_at_1" id="id_happened_at_1">',
)
def test_multivalue_field_validation(self):
def bad_names(value):
- if value == 'bad value':
- raise ValidationError('bad value not allowed')
+ if value == "bad value":
+ raise ValidationError("bad value not allowed")
class NameField(MultiValueField):
def __init__(self, fields=(), *args, **kwargs):
- fields = (CharField(label='First name', max_length=10),
- CharField(label='Last name', max_length=10))
+ fields = (
+ CharField(label="First name", max_length=10),
+ CharField(label="Last name", max_length=10),
+ )
super().__init__(fields=fields, *args, **kwargs)
def compress(self, data_list):
- return ' '.join(data_list)
+ return " ".join(data_list)
class NameForm(Form):
name = NameField(validators=[bad_names])
- form = NameForm(data={'name': ['bad', 'value']})
+ form = NameForm(data={"name": ["bad", "value"]})
form.full_clean()
self.assertFalse(form.is_valid())
- self.assertEqual(form.errors, {'name': ['bad value not allowed']})
- form = NameForm(data={'name': ['should be overly', 'long for the field names']})
+ self.assertEqual(form.errors, {"name": ["bad value not allowed"]})
+ form = NameForm(data={"name": ["should be overly", "long for the field names"]})
self.assertFalse(form.is_valid())
self.assertEqual(
- form.errors, {
- 'name': [
- 'Ensure this value has at most 10 characters (it has 16).',
- 'Ensure this value has at most 10 characters (it has 24).',
+ form.errors,
+ {
+ "name": [
+ "Ensure this value has at most 10 characters (it has 16).",
+ "Ensure this value has at most 10 characters (it has 24).",
],
- }
+ },
)
- form = NameForm(data={'name': ['fname', 'lname']})
+ form = NameForm(data={"name": ["fname", "lname"]})
self.assertTrue(form.is_valid())
- self.assertEqual(form.cleaned_data, {'name': 'fname lname'})
+ self.assertEqual(form.cleaned_data, {"name": "fname lname"})
def test_multivalue_deep_copy(self):
"""
#19298 -- MultiValueField needs to override the default as it needs
to deep-copy subfields:
"""
+
class ChoicesField(MultiValueField):
def __init__(self, fields=(), *args, **kwargs):
fields = (
- ChoiceField(label='Rank', choices=((1, 1), (2, 2))),
- CharField(label='Name', max_length=10),
+ ChoiceField(label="Rank", choices=((1, 1), (2, 2))),
+ CharField(label="Name", max_length=10),
)
super().__init__(fields=fields, *args, **kwargs)
@@ -2934,6 +3334,7 @@ Password: <input type="password" name="password" required>
"""
#23674 -- invalid initial data should not break form.changed_data()
"""
+
class DateAgeField(MultiValueField):
def __init__(self, fields=(), *args, **kwargs):
fields = (DateField(label="Date"), IntegerField(label="Age"))
@@ -2950,47 +3351,66 @@ Password: <input type="password" name="password" required>
class PhoneField(MultiValueField):
def __init__(self, *args, **kwargs):
fields = (
- CharField(label='Country Code', validators=[
- RegexValidator(r'^\+[0-9]{1,2}$', message='Enter a valid country code.')]),
- CharField(label='Phone Number'),
- CharField(label='Extension', error_messages={'incomplete': 'Enter an extension.'}),
- CharField(label='Label', required=False, help_text='E.g. home, work.'),
+ CharField(
+ label="Country Code",
+ validators=[
+ RegexValidator(
+ r"^\+[0-9]{1,2}$", message="Enter a valid country code."
+ )
+ ],
+ ),
+ CharField(label="Phone Number"),
+ CharField(
+ label="Extension",
+ error_messages={"incomplete": "Enter an extension."},
+ ),
+ CharField(
+ label="Label", required=False, help_text="E.g. home, work."
+ ),
)
super().__init__(fields, *args, **kwargs)
def compress(self, data_list):
if data_list:
- return '%s.%s ext. %s (label: %s)' % tuple(data_list)
+ return "%s.%s ext. %s (label: %s)" % tuple(data_list)
return None
# An empty value for any field will raise a `required` error on a
# required `MultiValueField`.
f = PhoneField()
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('')
+ f.clean("")
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(None)
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean([])
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean(['+61'])
+ f.clean(["+61"])
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean(['+61', '287654321', '123'])
- self.assertEqual('+61.287654321 ext. 123 (label: Home)', f.clean(['+61', '287654321', '123', 'Home']))
+ f.clean(["+61", "287654321", "123"])
+ self.assertEqual(
+ "+61.287654321 ext. 123 (label: Home)",
+ f.clean(["+61", "287654321", "123", "Home"]),
+ )
with self.assertRaisesMessage(ValidationError, "'Enter a valid country code.'"):
- f.clean(['61', '287654321', '123', 'Home'])
+ f.clean(["61", "287654321", "123", "Home"])
# Empty values for fields will NOT raise a `required` error on an
# optional `MultiValueField`
f = PhoneField(required=False)
- self.assertIsNone(f.clean(''))
+ self.assertIsNone(f.clean(""))
self.assertIsNone(f.clean(None))
self.assertIsNone(f.clean([]))
- self.assertEqual('+61. ext. (label: )', f.clean(['+61']))
- self.assertEqual('+61.287654321 ext. 123 (label: )', f.clean(['+61', '287654321', '123']))
- self.assertEqual('+61.287654321 ext. 123 (label: Home)', f.clean(['+61', '287654321', '123', 'Home']))
+ self.assertEqual("+61. ext. (label: )", f.clean(["+61"]))
+ self.assertEqual(
+ "+61.287654321 ext. 123 (label: )", f.clean(["+61", "287654321", "123"])
+ )
+ self.assertEqual(
+ "+61.287654321 ext. 123 (label: Home)",
+ f.clean(["+61", "287654321", "123", "Home"]),
+ )
with self.assertRaisesMessage(ValidationError, "'Enter a valid country code.'"):
- f.clean(['61', '287654321', '123', 'Home'])
+ f.clean(["61", "287654321", "123", "Home"])
# For a required `MultiValueField` with `require_all_fields=False`, a
# `required` error will only be raised if all fields are empty. Fields
@@ -2998,32 +3418,40 @@ Password: <input type="password" name="password" required>
# required field will raise an `incomplete` error.
f = PhoneField(require_all_fields=False)
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
- f.clean('')
+ f.clean("")
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean(None)
with self.assertRaisesMessage(ValidationError, "'This field is required.'"):
f.clean([])
with self.assertRaisesMessage(ValidationError, "'Enter a complete value.'"):
- f.clean(['+61'])
- self.assertEqual('+61.287654321 ext. 123 (label: )', f.clean(['+61', '287654321', '123']))
- with self.assertRaisesMessage(ValidationError, "'Enter a complete value.', 'Enter an extension.'"):
- f.clean(['', '', '', 'Home'])
+ f.clean(["+61"])
+ self.assertEqual(
+ "+61.287654321 ext. 123 (label: )", f.clean(["+61", "287654321", "123"])
+ )
+ with self.assertRaisesMessage(
+ ValidationError, "'Enter a complete value.', 'Enter an extension.'"
+ ):
+ f.clean(["", "", "", "Home"])
with self.assertRaisesMessage(ValidationError, "'Enter a valid country code.'"):
- f.clean(['61', '287654321', '123', 'Home'])
+ f.clean(["61", "287654321", "123", "Home"])
# For an optional `MultiValueField` with `require_all_fields=False`, we
# don't get any `required` error but we still get `incomplete` errors.
f = PhoneField(required=False, require_all_fields=False)
- self.assertIsNone(f.clean(''))
+ self.assertIsNone(f.clean(""))
self.assertIsNone(f.clean(None))
self.assertIsNone(f.clean([]))
with self.assertRaisesMessage(ValidationError, "'Enter a complete value.'"):
- f.clean(['+61'])
- self.assertEqual('+61.287654321 ext. 123 (label: )', f.clean(['+61', '287654321', '123']))
- with self.assertRaisesMessage(ValidationError, "'Enter a complete value.', 'Enter an extension.'"):
- f.clean(['', '', '', 'Home'])
+ f.clean(["+61"])
+ self.assertEqual(
+ "+61.287654321 ext. 123 (label: )", f.clean(["+61", "287654321", "123"])
+ )
+ with self.assertRaisesMessage(
+ ValidationError, "'Enter a complete value.', 'Enter an extension.'"
+ ):
+ f.clean(["", "", "", "Home"])
with self.assertRaisesMessage(ValidationError, "'Enter a valid country code.'"):
- f.clean(['61', '287654321', '123', 'Home'])
+ f.clean(["61", "287654321", "123", "Home"])
def test_multivalue_optional_subfields_rendering(self):
class PhoneWidget(MultiWidget):
@@ -3044,7 +3472,9 @@ Password: <input type="password" name="password" required>
phone2 = PhoneField(widget=PhoneWidget, required=False)
phone3 = PhoneField(widget=PhoneWidget, require_all_fields=False)
phone4 = PhoneField(
- widget=PhoneWidget, required=False, require_all_fields=False,
+ widget=PhoneWidget,
+ required=False,
+ require_all_fields=False,
)
form = PhoneForm(auto_id=False)
@@ -3063,42 +3493,41 @@ Password: <input type="password" name="password" required>
Form fields can customize what is considered as an empty value
for themselves (#19997).
"""
+
class CustomJSONField(CharField):
- empty_values = [None, '']
+ empty_values = [None, ""]
def to_python(self, value):
# Fake json.loads
- if value == '{}':
+ if value == "{}":
return {}
return super().to_python(value)
class JSONForm(forms.Form):
json = CustomJSONField()
- form = JSONForm(data={'json': '{}'})
+ form = JSONForm(data={"json": "{}"})
form.full_clean()
- self.assertEqual(form.cleaned_data, {'json': {}})
+ self.assertEqual(form.cleaned_data, {"json": {}})
def test_boundfield_label_tag(self):
class SomeForm(Form):
field = CharField()
- boundfield = SomeForm()['field']
+
+ boundfield = SomeForm()["field"]
testcases = [ # (args, kwargs, expected)
# without anything: just print the <label>
((), {}, '<%(tag)s for="id_field">Field:</%(tag)s>'),
-
# passing just one argument: overrides the field's label
- (('custom',), {}, '<%(tag)s for="id_field">custom:</%(tag)s>'),
-
+ (("custom",), {}, '<%(tag)s for="id_field">custom:</%(tag)s>'),
# the overridden label is escaped
- (('custom&',), {}, '<%(tag)s for="id_field">custom&amp;:</%(tag)s>'),
- ((mark_safe('custom&'),), {}, '<%(tag)s for="id_field">custom&:</%(tag)s>'),
-
+ (("custom&",), {}, '<%(tag)s for="id_field">custom&amp;:</%(tag)s>'),
+ ((mark_safe("custom&"),), {}, '<%(tag)s for="id_field">custom&:</%(tag)s>'),
# Passing attrs to add extra attributes on the <label>
(
(),
- {'attrs': {'class': 'pretty'}},
+ {"attrs": {"class": "pretty"}},
'<%(tag)s for="id_field" class="pretty">Field:</%(tag)s>',
),
]
@@ -3107,11 +3536,11 @@ Password: <input type="password" name="password" required>
with self.subTest(args=args, kwargs=kwargs):
self.assertHTMLEqual(
boundfield.label_tag(*args, **kwargs),
- expected % {'tag': 'label'},
+ expected % {"tag": "label"},
)
self.assertHTMLEqual(
boundfield.legend_tag(*args, **kwargs),
- expected % {'tag': 'legend'},
+ expected % {"tag": "legend"},
)
def test_boundfield_label_tag_no_id(self):
@@ -3119,19 +3548,21 @@ Password: <input type="password" name="password" required>
If a widget has no id, label_tag() and legend_tag() return the text
with no surrounding <label>.
"""
+
class SomeForm(Form):
field = CharField()
- boundfield = SomeForm(auto_id='')['field']
- self.assertHTMLEqual(boundfield.label_tag(), 'Field:')
- self.assertHTMLEqual(boundfield.legend_tag(), 'Field:')
- self.assertHTMLEqual(boundfield.label_tag('Custom&'), 'Custom&amp;:')
- self.assertHTMLEqual(boundfield.legend_tag('Custom&'), 'Custom&amp;:')
+ boundfield = SomeForm(auto_id="")["field"]
+
+ self.assertHTMLEqual(boundfield.label_tag(), "Field:")
+ self.assertHTMLEqual(boundfield.legend_tag(), "Field:")
+ self.assertHTMLEqual(boundfield.label_tag("Custom&"), "Custom&amp;:")
+ self.assertHTMLEqual(boundfield.legend_tag("Custom&"), "Custom&amp;:")
def test_boundfield_label_tag_custom_widget_id_for_label(self):
class CustomIdForLabelTextInput(TextInput):
def id_for_label(self, id):
- return 'custom_' + id
+ return "custom_" + id
class EmptyIdForLabelTextInput(TextInput):
def id_for_label(self, id):
@@ -3142,18 +3573,21 @@ Password: <input type="password" name="password" required>
empty = CharField(widget=EmptyIdForLabelTextInput)
form = SomeForm()
- self.assertHTMLEqual(form['custom'].label_tag(), '<label for="custom_id_custom">Custom:</label>')
self.assertHTMLEqual(
- form['custom'].legend_tag(),
+ form["custom"].label_tag(), '<label for="custom_id_custom">Custom:</label>'
+ )
+ self.assertHTMLEqual(
+ form["custom"].legend_tag(),
'<legend for="custom_id_custom">Custom:</legend>',
)
- self.assertHTMLEqual(form['empty'].label_tag(), '<label>Empty:</label>')
- self.assertHTMLEqual(form['empty'].legend_tag(), '<legend>Empty:</legend>')
+ self.assertHTMLEqual(form["empty"].label_tag(), "<label>Empty:</label>")
+ self.assertHTMLEqual(form["empty"].legend_tag(), "<legend>Empty:</legend>")
def test_boundfield_empty_label(self):
class SomeForm(Form):
- field = CharField(label='')
- boundfield = SomeForm()['field']
+ field = CharField(label="")
+
+ boundfield = SomeForm()["field"]
self.assertHTMLEqual(boundfield.label_tag(), '<label for="id_field"></label>')
self.assertHTMLEqual(
@@ -3163,38 +3597,40 @@ Password: <input type="password" name="password" required>
def test_boundfield_id_for_label(self):
class SomeForm(Form):
- field = CharField(label='')
+ field = CharField(label="")
- self.assertEqual(SomeForm()['field'].id_for_label, 'id_field')
+ self.assertEqual(SomeForm()["field"].id_for_label, "id_field")
def test_boundfield_id_for_label_override_by_attrs(self):
"""
If an id is provided in `Widget.attrs`, it overrides the generated ID,
unless it is `None`.
"""
+
class SomeForm(Form):
- field = CharField(widget=TextInput(attrs={'id': 'myCustomID'}))
- field_none = CharField(widget=TextInput(attrs={'id': None}))
+ field = CharField(widget=TextInput(attrs={"id": "myCustomID"}))
+ field_none = CharField(widget=TextInput(attrs={"id": None}))
form = SomeForm()
- self.assertEqual(form['field'].id_for_label, 'myCustomID')
- self.assertEqual(form['field_none'].id_for_label, 'id_field_none')
+ self.assertEqual(form["field"].id_for_label, "myCustomID")
+ self.assertEqual(form["field_none"].id_for_label, "id_field_none")
def test_boundfield_subwidget_id_for_label(self):
"""
If auto_id is provided when initializing the form, the generated ID in
subwidgets must reflect that prefix.
"""
+
class SomeForm(Form):
field = MultipleChoiceField(
- choices=[('a', 'A'), ('b', 'B')],
+ choices=[("a", "A"), ("b", "B")],
widget=CheckboxSelectMultiple,
)
- form = SomeForm(auto_id='prefix_%s')
- subwidgets = form['field'].subwidgets
- self.assertEqual(subwidgets[0].id_for_label, 'prefix_field_0')
- self.assertEqual(subwidgets[1].id_for_label, 'prefix_field_1')
+ form = SomeForm(auto_id="prefix_%s")
+ subwidgets = form["field"].subwidgets
+ self.assertEqual(subwidgets[0].id_for_label, "prefix_field_0")
+ self.assertEqual(subwidgets[1].id_for_label, "prefix_field_1")
def test_boundfield_widget_type(self):
class SomeForm(Form):
@@ -3202,28 +3638,33 @@ Password: <input type="password" name="password" required>
birthday = SplitDateTimeField(widget=SplitHiddenDateTimeWidget)
f = SomeForm()
- self.assertEqual(f['first_name'].widget_type, 'text')
- self.assertEqual(f['birthday'].widget_type, 'splithiddendatetime')
+ self.assertEqual(f["first_name"].widget_type, "text")
+ self.assertEqual(f["birthday"].widget_type, "splithiddendatetime")
def test_boundfield_css_classes(self):
form = Person()
- field = form['first_name']
- self.assertEqual(field.css_classes(), '')
- self.assertEqual(field.css_classes(extra_classes=''), '')
- self.assertEqual(field.css_classes(extra_classes='test'), 'test')
- self.assertEqual(field.css_classes(extra_classes='test test'), 'test')
+ field = form["first_name"]
+ self.assertEqual(field.css_classes(), "")
+ self.assertEqual(field.css_classes(extra_classes=""), "")
+ self.assertEqual(field.css_classes(extra_classes="test"), "test")
+ self.assertEqual(field.css_classes(extra_classes="test test"), "test")
def test_label_suffix_override(self):
"""
BoundField label_suffix (if provided) overrides Form label_suffix
"""
+
class SomeForm(Form):
field = CharField()
- boundfield = SomeForm(label_suffix='!')['field']
- self.assertHTMLEqual(boundfield.label_tag(label_suffix='$'), '<label for="id_field">Field$</label>')
+ boundfield = SomeForm(label_suffix="!")["field"]
+
+ self.assertHTMLEqual(
+ boundfield.label_tag(label_suffix="$"),
+ '<label for="id_field">Field$</label>',
+ )
self.assertHTMLEqual(
- boundfield.legend_tag(label_suffix='$'),
+ boundfield.legend_tag(label_suffix="$"),
'<legend for="id_field">Field$</legend>',
)
@@ -3233,16 +3674,18 @@ Password: <input type="password" name="password" required>
bar = CharField()
def clean(self):
- raise ValidationError('Non-field error.', code='secret', params={'a': 1, 'b': 2})
+ raise ValidationError(
+ "Non-field error.", code="secret", params={"a": 1, "b": 2}
+ )
form = MyForm({})
self.assertIs(form.is_valid(), False)
errors = form.errors.as_text()
control = [
- '* foo\n * This field is required.',
- '* bar\n * This field is required.',
- '* __all__\n * Non-field error.',
+ "* foo\n * This field is required.",
+ "* bar\n * This field is required.",
+ "* __all__\n * Non-field error.",
]
for error in control:
self.assertIn(error, errors)
@@ -3258,30 +3701,31 @@ Password: <input type="password" name="password" required>
errors = form.errors.get_json_data()
control = {
- 'foo': [{'code': 'required', 'message': 'This field is required.'}],
- 'bar': [{'code': 'required', 'message': 'This field is required.'}],
- '__all__': [{'code': 'secret', 'message': 'Non-field error.'}]
+ "foo": [{"code": "required", "message": "This field is required."}],
+ "bar": [{"code": "required", "message": "This field is required."}],
+ "__all__": [{"code": "secret", "message": "Non-field error."}],
}
self.assertEqual(errors, control)
self.assertEqual(json.dumps(errors), form.errors.as_json())
def test_error_dict_as_json_escape_html(self):
"""#21962 - adding html escape flag to ErrorDict"""
+
class MyForm(Form):
foo = CharField()
bar = CharField()
def clean(self):
raise ValidationError(
- '<p>Non-field error.</p>',
- code='secret',
- params={'a': 1, 'b': 2},
+ "<p>Non-field error.</p>",
+ code="secret",
+ params={"a": 1, "b": 2},
)
control = {
- 'foo': [{'code': 'required', 'message': 'This field is required.'}],
- 'bar': [{'code': 'required', 'message': 'This field is required.'}],
- '__all__': [{'code': 'secret', 'message': '<p>Non-field error.</p>'}]
+ "foo": [{"code": "required", "message": "This field is required."}],
+ "bar": [{"code": "required", "message": "This field is required."}],
+ "__all__": [{"code": "secret", "message": "<p>Non-field error.</p>"}],
}
form = MyForm({})
@@ -3290,57 +3734,52 @@ Password: <input type="password" name="password" required>
errors = json.loads(form.errors.as_json())
self.assertEqual(errors, control)
- escaped_error = '&lt;p&gt;Non-field error.&lt;/p&gt;'
+ escaped_error = "&lt;p&gt;Non-field error.&lt;/p&gt;"
self.assertEqual(
- form.errors.get_json_data(escape_html=True)['__all__'][0]['message'],
- escaped_error
+ form.errors.get_json_data(escape_html=True)["__all__"][0]["message"],
+ escaped_error,
)
errors = json.loads(form.errors.as_json(escape_html=True))
- control['__all__'][0]['message'] = escaped_error
+ control["__all__"][0]["message"] = escaped_error
self.assertEqual(errors, control)
def test_error_list(self):
e = ErrorList()
- e.append('Foo')
- e.append(ValidationError('Foo%(bar)s', code='foobar', params={'bar': 'bar'}))
+ e.append("Foo")
+ e.append(ValidationError("Foo%(bar)s", code="foobar", params={"bar": "bar"}))
self.assertIsInstance(e, list)
- self.assertIn('Foo', e)
- self.assertIn('Foo', ValidationError(e))
+ self.assertIn("Foo", e)
+ self.assertIn("Foo", ValidationError(e))
- self.assertEqual(
- e.as_text(),
- '* Foo\n* Foobar'
- )
+ self.assertEqual(e.as_text(), "* Foo\n* Foobar")
self.assertEqual(
- e.as_ul(),
- '<ul class="errorlist"><li>Foo</li><li>Foobar</li></ul>'
+ e.as_ul(), '<ul class="errorlist"><li>Foo</li><li>Foobar</li></ul>'
)
errors = e.get_json_data()
self.assertEqual(
errors,
- [{"message": "Foo", "code": ""}, {"message": "Foobar", "code": "foobar"}]
+ [{"message": "Foo", "code": ""}, {"message": "Foobar", "code": "foobar"}],
)
self.assertEqual(json.dumps(errors), e.as_json())
def test_error_list_class_not_specified(self):
e = ErrorList()
- e.append('Foo')
- e.append(ValidationError('Foo%(bar)s', code='foobar', params={'bar': 'bar'}))
+ e.append("Foo")
+ e.append(ValidationError("Foo%(bar)s", code="foobar", params={"bar": "bar"}))
self.assertEqual(
- e.as_ul(),
- '<ul class="errorlist"><li>Foo</li><li>Foobar</li></ul>'
+ e.as_ul(), '<ul class="errorlist"><li>Foo</li><li>Foobar</li></ul>'
)
def test_error_list_class_has_one_class_specified(self):
- e = ErrorList(error_class='foobar-error-class')
- e.append('Foo')
- e.append(ValidationError('Foo%(bar)s', code='foobar', params={'bar': 'bar'}))
+ e = ErrorList(error_class="foobar-error-class")
+ e.append("Foo")
+ e.append(ValidationError("Foo%(bar)s", code="foobar", params={"bar": "bar"}))
self.assertEqual(
e.as_ul(),
- '<ul class="errorlist foobar-error-class"><li>Foo</li><li>Foobar</li></ul>'
+ '<ul class="errorlist foobar-error-class"><li>Foo</li><li>Foobar</li></ul>',
)
def test_error_list_with_hidden_field_errors_has_correct_class(self):
@@ -3348,21 +3787,21 @@ Password: <input type="password" name="password" required>
first_name = CharField()
last_name = CharField(widget=HiddenInput)
- p = Person({'first_name': 'John'})
+ p = Person({"first_name": "John"})
self.assertHTMLEqual(
p.as_ul(),
"""<li><ul class="errorlist nonfield">
<li>(Hidden field last_name) This field is required.</li></ul></li><li>
<label for="id_first_name">First name:</label>
<input id="id_first_name" name="first_name" type="text" value="John" required>
-<input id="id_last_name" name="last_name" type="hidden"></li>"""
+<input id="id_last_name" name="last_name" type="hidden"></li>""",
)
self.assertHTMLEqual(
p.as_p(),
"""<ul class="errorlist nonfield"><li>(Hidden field last_name) This field is required.</li></ul>
<p><label for="id_first_name">First name:</label>
<input id="id_first_name" name="first_name" type="text" value="John" required>
-<input id="id_last_name" name="last_name" type="hidden"></p>"""
+<input id="id_last_name" name="last_name" type="hidden"></p>""",
)
self.assertHTMLEqual(
p.as_table(),
@@ -3370,7 +3809,7 @@ Password: <input type="password" name="password" required>
<li>(Hidden field last_name) This field is required.</li></ul></td></tr>
<tr><th><label for="id_first_name">First name:</label></th><td>
<input id="id_first_name" name="first_name" type="text" value="John" required>
-<input id="id_last_name" name="last_name" type="hidden"></td></tr>"""
+<input id="id_last_name" name="last_name" type="hidden"></td></tr>""",
)
def test_error_list_with_non_field_errors_has_correct_class(self):
@@ -3379,12 +3818,12 @@ Password: <input type="password" name="password" required>
last_name = CharField()
def clean(self):
- raise ValidationError('Generic validation error')
+ raise ValidationError("Generic validation error")
- p = Person({'first_name': 'John', 'last_name': 'Lennon'})
+ p = Person({"first_name": "John", "last_name": "Lennon"})
self.assertHTMLEqual(
str(p.non_field_errors()),
- '<ul class="errorlist nonfield"><li>Generic validation error</li></ul>'
+ '<ul class="errorlist nonfield"><li>Generic validation error</li></ul>',
)
self.assertHTMLEqual(
p.as_ul(),
@@ -3393,11 +3832,10 @@ Password: <input type="password" name="password" required>
<li><label for="id_first_name">First name:</label>
<input id="id_first_name" name="first_name" type="text" value="John" required></li>
<li><label for="id_last_name">Last name:</label>
-<input id="id_last_name" name="last_name" type="text" value="Lennon" required></li>"""
+<input id="id_last_name" name="last_name" type="text" value="Lennon" required></li>""",
)
self.assertHTMLEqual(
- p.non_field_errors().as_text(),
- '* Generic validation error'
+ p.non_field_errors().as_text(), "* Generic validation error"
)
self.assertHTMLEqual(
p.as_p(),
@@ -3405,7 +3843,7 @@ Password: <input type="password" name="password" required>
<p><label for="id_first_name">First name:</label>
<input id="id_first_name" name="first_name" type="text" value="John" required></p>
<p><label for="id_last_name">Last name:</label>
-<input id="id_last_name" name="last_name" type="text" value="Lennon" required></p>"""
+<input id="id_last_name" name="last_name" type="text" value="Lennon" required></p>""",
)
self.assertHTMLEqual(
p.as_table(),
@@ -3413,7 +3851,7 @@ Password: <input type="password" name="password" required>
<tr><th><label for="id_first_name">First name:</label></th><td>
<input id="id_first_name" name="first_name" type="text" value="John" required></td></tr>
<tr><th><label for="id_last_name">Last name:</label></th><td>
-<input id="id_last_name" name="last_name" type="text" value="Lennon" required></td></tr>"""
+<input id="id_last_name" name="last_name" type="text" value="Lennon" required></td></tr>""",
)
def test_error_escaping(self):
@@ -3426,7 +3864,7 @@ Password: <input type="password" name="password" required>
clean_visible = clean_hidden
- form = TestForm({'hidden': 'a', 'visible': 'b'})
+ form = TestForm({"hidden": "a", "visible": "b"})
form.is_valid()
self.assertHTMLEqual(
form.as_ul(),
@@ -3434,7 +3872,7 @@ Password: <input type="password" name="password" required>
'<li><ul class="errorlist"><li>Foo &amp; &quot;bar&quot;!</li></ul>'
'<label for="id_visible">Visible:</label> '
'<input type="text" name="visible" value="b" id="id_visible" required>'
- '<input type="hidden" name="hidden" value="a" id="id_hidden"></li>'
+ '<input type="hidden" name="hidden" value="a" id="id_hidden"></li>',
)
def test_baseform_repr(self):
@@ -3443,25 +3881,43 @@ Password: <input type="password" name="password" required>
form.
"""
p = Person()
- self.assertEqual(repr(p), "<Person bound=False, valid=Unknown, fields=(first_name;last_name;birthday)>")
- p = Person({'first_name': 'John', 'last_name': 'Lennon', 'birthday': '1940-10-9'})
- self.assertEqual(repr(p), "<Person bound=True, valid=Unknown, fields=(first_name;last_name;birthday)>")
+ self.assertEqual(
+ repr(p),
+ "<Person bound=False, valid=Unknown, fields=(first_name;last_name;birthday)>",
+ )
+ p = Person(
+ {"first_name": "John", "last_name": "Lennon", "birthday": "1940-10-9"}
+ )
+ self.assertEqual(
+ repr(p),
+ "<Person bound=True, valid=Unknown, fields=(first_name;last_name;birthday)>",
+ )
p.is_valid()
- self.assertEqual(repr(p), "<Person bound=True, valid=True, fields=(first_name;last_name;birthday)>")
- p = Person({'first_name': 'John', 'last_name': 'Lennon', 'birthday': 'fakedate'})
+ self.assertEqual(
+ repr(p),
+ "<Person bound=True, valid=True, fields=(first_name;last_name;birthday)>",
+ )
+ p = Person(
+ {"first_name": "John", "last_name": "Lennon", "birthday": "fakedate"}
+ )
p.is_valid()
- self.assertEqual(repr(p), "<Person bound=True, valid=False, fields=(first_name;last_name;birthday)>")
+ self.assertEqual(
+ repr(p),
+ "<Person bound=True, valid=False, fields=(first_name;last_name;birthday)>",
+ )
def test_baseform_repr_dont_trigger_validation(self):
"""
BaseForm.__repr__() shouldn't trigger the form validation.
"""
- p = Person({'first_name': 'John', 'last_name': 'Lennon', 'birthday': 'fakedate'})
+ p = Person(
+ {"first_name": "John", "last_name": "Lennon", "birthday": "fakedate"}
+ )
repr(p)
with self.assertRaises(AttributeError):
p.cleaned_data
self.assertFalse(p.is_valid())
- self.assertEqual(p.cleaned_data, {'first_name': 'John', 'last_name': 'Lennon'})
+ self.assertEqual(p.cleaned_data, {"first_name": "John", "last_name": "Lennon"})
def test_accessing_clean(self):
class UserForm(Form):
@@ -3472,13 +3928,13 @@ Password: <input type="password" name="password" required>
data = self.cleaned_data
if not self.errors:
- data['username'] = data['username'].lower()
+ data["username"] = data["username"].lower()
return data
- f = UserForm({'username': 'SirRobin', 'password': 'blue'})
+ f = UserForm({"username": "SirRobin", "password": "blue"})
self.assertTrue(f.is_valid())
- self.assertEqual(f.cleaned_data['username'], 'sirrobin')
+ self.assertEqual(f.cleaned_data["username"], "sirrobin")
def test_changing_cleaned_data_nothing_returned(self):
class UserForm(Form):
@@ -3486,12 +3942,12 @@ Password: <input type="password" name="password" required>
password = CharField(widget=PasswordInput)
def clean(self):
- self.cleaned_data['username'] = self.cleaned_data['username'].lower()
+ self.cleaned_data["username"] = self.cleaned_data["username"].lower()
# don't return anything
- f = UserForm({'username': 'SirRobin', 'password': 'blue'})
+ f = UserForm({"username": "SirRobin", "password": "blue"})
self.assertTrue(f.is_valid())
- self.assertEqual(f.cleaned_data['username'], 'sirrobin')
+ self.assertEqual(f.cleaned_data["username"], "sirrobin")
def test_changing_cleaned_data_in_clean(self):
class UserForm(Form):
@@ -3503,13 +3959,13 @@ Password: <input type="password" name="password" required>
# Return a different dict. We have not changed self.cleaned_data.
return {
- 'username': data['username'].lower(),
- 'password': 'this_is_not_a_secret',
+ "username": data["username"].lower(),
+ "password": "this_is_not_a_secret",
}
- f = UserForm({'username': 'SirRobin', 'password': 'blue'})
+ f = UserForm({"username": "SirRobin", "password": "blue"})
self.assertTrue(f.is_valid())
- self.assertEqual(f.cleaned_data['username'], 'sirrobin')
+ self.assertEqual(f.cleaned_data["username"], "sirrobin")
def test_multipart_encoded_form(self):
class FormWithoutFile(Form):
@@ -3531,10 +3987,10 @@ Password: <input type="password" name="password" required>
username = CharField()
form = SimpleForm()
- self.assertTrue(hasattr(SimpleForm, '__html__'))
+ self.assertTrue(hasattr(SimpleForm, "__html__"))
self.assertEqual(str(form), form.__html__())
- self.assertTrue(hasattr(form['username'], '__html__'))
- self.assertEqual(str(form['username']), form['username'].__html__())
+ self.assertTrue(hasattr(form["username"], "__html__"))
+ self.assertEqual(str(form["username"]), form["username"].__html__())
def test_use_required_attribute_true(self):
class MyForm(Form):
@@ -3542,7 +3998,7 @@ Password: <input type="password" name="password" required>
f1 = CharField(max_length=30)
f2 = CharField(max_length=30, required=False)
f3 = CharField(widget=Textarea)
- f4 = ChoiceField(choices=[('P', 'Python'), ('J', 'Java')])
+ f4 = ChoiceField(choices=[("P", "Python"), ("J", "Java")])
form = MyForm()
self.assertHTMLEqual(
@@ -3550,11 +4006,11 @@ Password: <input type="password" name="password" required>
'<p><label for="id_f1">F1:</label> <input id="id_f1" maxlength="30" name="f1" type="text" required></p>'
'<p><label for="id_f2">F2:</label> <input id="id_f2" maxlength="30" name="f2" type="text"></p>'
'<p><label for="id_f3">F3:</label> <textarea cols="40" id="id_f3" name="f3" rows="10" required>'
- '</textarea></p>'
+ "</textarea></p>"
'<p><label for="id_f4">F4:</label> <select id="id_f4" name="f4">'
'<option value="P">Python</option>'
'<option value="J">Java</option>'
- '</select></p>',
+ "</select></p>",
)
self.assertHTMLEqual(
form.as_ul(),
@@ -3562,11 +4018,11 @@ Password: <input type="password" name="password" required>
'<input id="id_f1" maxlength="30" name="f1" type="text" required></li>'
'<li><label for="id_f2">F2:</label> <input id="id_f2" maxlength="30" name="f2" type="text"></li>'
'<li><label for="id_f3">F3:</label> <textarea cols="40" id="id_f3" name="f3" rows="10" required>'
- '</textarea></li>'
+ "</textarea></li>"
'<li><label for="id_f4">F4:</label> <select id="id_f4" name="f4">'
'<option value="P">Python</option>'
'<option value="J">Java</option>'
- '</select></li>',
+ "</select></li>",
)
self.assertHTMLEqual(
form.as_table(),
@@ -3576,11 +4032,11 @@ Password: <input type="password" name="password" required>
'<td><input id="id_f2" maxlength="30" name="f2" type="text"></td></tr>'
'<tr><th><label for="id_f3">F3:</label></th>'
'<td><textarea cols="40" id="id_f3" name="f3" rows="10" required>'
- '</textarea></td></tr>'
+ "</textarea></td></tr>"
'<tr><th><label for="id_f4">F4:</label></th><td><select id="id_f4" name="f4">'
'<option value="P">Python</option>'
'<option value="J">Java</option>'
- '</select></td></tr>',
+ "</select></td></tr>",
)
def test_use_required_attribute_false(self):
@@ -3589,7 +4045,7 @@ Password: <input type="password" name="password" required>
f1 = CharField(max_length=30)
f2 = CharField(max_length=30, required=False)
f3 = CharField(widget=Textarea)
- f4 = ChoiceField(choices=[('P', 'Python'), ('J', 'Java')])
+ f4 = ChoiceField(choices=[("P", "Python"), ("J", "Java")])
form = MyForm()
self.assertHTMLEqual(
@@ -3597,22 +4053,22 @@ Password: <input type="password" name="password" required>
'<p><label for="id_f1">F1:</label> <input id="id_f1" maxlength="30" name="f1" type="text"></p>'
'<p><label for="id_f2">F2:</label> <input id="id_f2" maxlength="30" name="f2" type="text"></p>'
'<p><label for="id_f3">F3:</label> <textarea cols="40" id="id_f3" name="f3" rows="10">'
- '</textarea></p>'
+ "</textarea></p>"
'<p><label for="id_f4">F4:</label> <select id="id_f4" name="f4">'
'<option value="P">Python</option>'
'<option value="J">Java</option>'
- '</select></p>',
+ "</select></p>",
)
self.assertHTMLEqual(
form.as_ul(),
'<li><label for="id_f1">F1:</label> <input id="id_f1" maxlength="30" name="f1" type="text"></li>'
'<li><label for="id_f2">F2:</label> <input id="id_f2" maxlength="30" name="f2" type="text"></li>'
'<li><label for="id_f3">F3:</label> <textarea cols="40" id="id_f3" name="f3" rows="10">'
- '</textarea></li>'
+ "</textarea></li>"
'<li><label for="id_f4">F4:</label> <select id="id_f4" name="f4">'
'<option value="P">Python</option>'
'<option value="J">Java</option>'
- '</select></li>',
+ "</select></li>",
)
self.assertHTMLEqual(
form.as_table(),
@@ -3621,11 +4077,11 @@ Password: <input type="password" name="password" required>
'<tr><th><label for="id_f2">F2:</label></th>'
'<td><input id="id_f2" maxlength="30" name="f2" type="text"></td></tr>'
'<tr><th><label for="id_f3">F3:</label></th><td><textarea cols="40" id="id_f3" name="f3" rows="10">'
- '</textarea></td></tr>'
+ "</textarea></td></tr>"
'<tr><th><label for="id_f4">F4:</label></th><td><select id="id_f4" name="f4">'
'<option value="P">Python</option>'
'<option value="J">Java</option>'
- '</select></td></tr>',
+ "</select></td></tr>",
)
def test_only_hidden_fields(self):
@@ -3637,23 +4093,23 @@ Password: <input type="password" name="password" required>
self.assertHTMLEqual(
f.as_p(),
'<ul class="errorlist nonfield">'
- '<li>(Hidden field data) This field is required.</li></ul>\n<p> '
- '<input type="hidden" name="data" id="id_data"></p>'
+ "<li>(Hidden field data) This field is required.</li></ul>\n<p> "
+ '<input type="hidden" name="data" id="id_data"></p>',
)
self.assertHTMLEqual(
f.as_table(),
'<tr><td colspan="2"><ul class="errorlist nonfield">'
- '<li>(Hidden field data) This field is required.</li></ul>'
- '<input type="hidden" name="data" id="id_data"></td></tr>'
+ "<li>(Hidden field data) This field is required.</li></ul>"
+ '<input type="hidden" name="data" id="id_data"></td></tr>',
)
def test_field_named_data(self):
class DataForm(Form):
data = CharField(max_length=10)
- f = DataForm({'data': 'xyzzy'})
+ f = DataForm({"data": "xyzzy"})
self.assertTrue(f.is_valid())
- self.assertEqual(f.cleaned_data, {'data': 'xyzzy'})
+ self.assertEqual(f.cleaned_data, {"data": "xyzzy"})
def test_empty_data_files_multi_value_dict(self):
p = Person()
@@ -3663,7 +4119,7 @@ Password: <input type="password" name="password" required>
def test_field_deep_copy_error_messages(self):
class CustomCharField(CharField):
def __init__(self, **kwargs):
- kwargs['error_messages'] = {'invalid': 'Form custom error message.'}
+ kwargs["error_messages"] = {"invalid": "Form custom error message."}
super().__init__(**kwargs)
field = CustomCharField()
@@ -3673,8 +4129,10 @@ Password: <input type="password" name="password" required>
def test_label_does_not_include_new_line(self):
form = Person()
- field = form['first_name']
- self.assertEqual(field.label_tag(), '<label for="id_first_name">First name:</label>')
+ field = form["first_name"]
+ self.assertEqual(
+ field.label_tag(), '<label for="id_first_name">First name:</label>'
+ )
self.assertEqual(
field.legend_tag(),
'<legend for="id_first_name">First name:</legend>',
@@ -3683,13 +4141,13 @@ Password: <input type="password" name="password" required>
@override_settings(USE_THOUSAND_SEPARATOR=True)
def test_label_attrs_not_localized(self):
form = Person()
- field = form['first_name']
+ field = form["first_name"]
self.assertHTMLEqual(
- field.label_tag(attrs={'number': 9999}),
+ field.label_tag(attrs={"number": 9999}),
'<label number="9999" for="id_first_name">First name:</label>',
)
self.assertHTMLEqual(
- field.legend_tag(attrs={'number': 9999}),
+ field.legend_tag(attrs={"number": 9999}),
'<legend number="9999" for="id_first_name">First name:</legend>',
)
@@ -3704,7 +4162,6 @@ class CustomRenderer(DjangoTemplates):
class RendererTests(SimpleTestCase):
-
def test_default(self):
form = Form()
self.assertEqual(form.renderer, get_default_renderer())
@@ -3744,54 +4201,55 @@ class RendererTests(SimpleTestCase):
class TemplateTests(SimpleTestCase):
def test_iterate_radios(self):
- f = FrameworkForm(auto_id='id_%s')
+ f = FrameworkForm(auto_id="id_%s")
t = Template(
- '{% for radio in form.language %}'
+ "{% for radio in form.language %}"
'<div class="myradio">{{ radio }}</div>'
- '{% endfor %}'
+ "{% endfor %}"
)
self.assertHTMLEqual(
- t.render(Context({'form': f})),
+ t.render(Context({"form": f})),
'<div class="myradio"><label for="id_language_0">'
'<input id="id_language_0" name="language" type="radio" value="P" '
- 'required> Python</label></div>'
+ "required> Python</label></div>"
'<div class="myradio"><label for="id_language_1">'
'<input id="id_language_1" name="language" type="radio" value="J" '
- 'required> Java</label></div>',
+ "required> Java</label></div>",
)
def test_iterate_checkboxes(self):
- f = SongForm({'composers': ['J', 'P']}, auto_id=False)
+ f = SongForm({"composers": ["J", "P"]}, auto_id=False)
t = Template(
- '{% for checkbox in form.composers %}'
+ "{% for checkbox in form.composers %}"
'<div class="mycheckbox">{{ checkbox }}</div>'
- '{% endfor %}'
+ "{% endfor %}"
)
self.assertHTMLEqual(
- t.render(Context({'form': f})),
+ t.render(Context({"form": f})),
'<div class="mycheckbox"><label>'
'<input checked name="composers" type="checkbox" value="J"> '
- 'John Lennon</label></div>'
+ "John Lennon</label></div>"
'<div class="mycheckbox"><label>'
'<input checked name="composers" type="checkbox" value="P"> '
- 'Paul McCartney</label></div>',
+ "Paul McCartney</label></div>",
)
def test_templates_with_forms(self):
class UserRegistration(Form):
- username = CharField(max_length=10, help_text=(
- "Good luck picking a username that doesn't already exist."
- ))
+ username = CharField(
+ max_length=10,
+ help_text=("Good luck picking a username that doesn't already exist."),
+ )
password1 = CharField(widget=PasswordInput)
password2 = CharField(widget=PasswordInput)
def clean(self):
if (
- self.cleaned_data.get('password1') and
- self.cleaned_data.get('password2') and
- self.cleaned_data['password1'] != self.cleaned_data['password2']
+ self.cleaned_data.get("password1")
+ and self.cleaned_data.get("password2")
+ and self.cleaned_data["password1"] != self.cleaned_data["password2"]
):
- raise ValidationError('Please make sure your passwords match.')
+ raise ValidationError("Please make sure your passwords match.")
return self.cleaned_data
# There is full flexibility in displaying form fields in a template.
@@ -3800,169 +4258,169 @@ class TemplateTests(SimpleTestCase):
# responsibility of displaying all the errors, including any that might
# not be associated with a particular field.
t = Template(
- '<form>'
- '{{ form.username.errors.as_ul }}'
- '<p><label>Your username: {{ form.username }}</label></p>'
- '{{ form.password1.errors.as_ul }}'
- '<p><label>Password: {{ form.password1 }}</label></p>'
- '{{ form.password2.errors.as_ul }}'
- '<p><label>Password (again): {{ form.password2 }}</label></p>'
+ "<form>"
+ "{{ form.username.errors.as_ul }}"
+ "<p><label>Your username: {{ form.username }}</label></p>"
+ "{{ form.password1.errors.as_ul }}"
+ "<p><label>Password: {{ form.password1 }}</label></p>"
+ "{{ form.password2.errors.as_ul }}"
+ "<p><label>Password (again): {{ form.password2 }}</label></p>"
'<input type="submit" required>'
- '</form>'
+ "</form>"
)
f = UserRegistration(auto_id=False)
self.assertHTMLEqual(
- t.render(Context({'form': f})),
- '<form>'
- '<p><label>Your username: '
+ t.render(Context({"form": f})),
+ "<form>"
+ "<p><label>Your username: "
'<input type="text" name="username" maxlength="10" required></label></p>'
- '<p><label>Password: '
+ "<p><label>Password: "
'<input type="password" name="password1" required></label></p>'
- '<p><label>Password (again): '
+ "<p><label>Password (again): "
'<input type="password" name="password2" required></label></p>'
'<input type="submit" required>'
- '</form>',
+ "</form>",
)
- f = UserRegistration({'username': 'django'}, auto_id=False)
+ f = UserRegistration({"username": "django"}, auto_id=False)
self.assertHTMLEqual(
- t.render(Context({'form': f})),
- '<form>'
- '<p><label>Your username: '
+ t.render(Context({"form": f})),
+ "<form>"
+ "<p><label>Your username: "
'<input type="text" name="username" value="django" maxlength="10" required>'
- '</label></p>'
+ "</label></p>"
'<ul class="errorlist"><li>This field is required.</li></ul><p>'
- '<label>Password: '
+ "<label>Password: "
'<input type="password" name="password1" required></label></p>'
'<ul class="errorlist"><li>This field is required.</li></ul>'
- '<p><label>Password (again): '
+ "<p><label>Password (again): "
'<input type="password" name="password2" required></label></p>'
'<input type="submit" required>'
- '</form>',
+ "</form>",
)
# Use form.[field].label to output a field's label. 'label' for a field
# can by specified by using the 'label' argument to a Field class. If
# 'label' is not specified, Django will use the field name with
# underscores converted to spaces, and the initial letter capitalized.
t = Template(
- '<form>'
- '<p><label>{{ form.username.label }}: {{ form.username }}</label></p>'
- '<p><label>{{ form.password1.label }}: {{ form.password1 }}</label></p>'
- '<p><label>{{ form.password2.label }}: {{ form.password2 }}</label></p>'
+ "<form>"
+ "<p><label>{{ form.username.label }}: {{ form.username }}</label></p>"
+ "<p><label>{{ form.password1.label }}: {{ form.password1 }}</label></p>"
+ "<p><label>{{ form.password2.label }}: {{ form.password2 }}</label></p>"
'<input type="submit" required>'
- '</form>'
+ "</form>"
)
f = UserRegistration(auto_id=False)
self.assertHTMLEqual(
- t.render(Context({'form': f})),
- '<form>'
- '<p><label>Username: '
+ t.render(Context({"form": f})),
+ "<form>"
+ "<p><label>Username: "
'<input type="text" name="username" maxlength="10" required></label></p>'
- '<p><label>Password1: '
+ "<p><label>Password1: "
'<input type="password" name="password1" required></label></p>'
- '<p><label>Password2: '
+ "<p><label>Password2: "
'<input type="password" name="password2" required></label></p>'
'<input type="submit" required>'
- '</form>',
+ "</form>",
)
# Use form.[field].label_tag to output a field's label with a <label>
# tag wrapped around it, but *only* if the given field has an "id"
# attribute. Recall from above that passing the "auto_id" argument to a
# Form gives each field an "id" attribute.
t = Template(
- '<form>'
- '<p>{{ form.username.label_tag }} {{ form.username }}</p>'
- '<p>{{ form.password1.label_tag }} {{ form.password1 }}</p>'
- '<p>{{ form.password2.label_tag }} {{ form.password2 }}</p>'
+ "<form>"
+ "<p>{{ form.username.label_tag }} {{ form.username }}</p>"
+ "<p>{{ form.password1.label_tag }} {{ form.password1 }}</p>"
+ "<p>{{ form.password2.label_tag }} {{ form.password2 }}</p>"
'<input type="submit" required>'
- '</form>'
+ "</form>"
)
self.assertHTMLEqual(
- t.render(Context({'form': f})),
- '<form>'
- '<p>Username: '
+ t.render(Context({"form": f})),
+ "<form>"
+ "<p>Username: "
'<input type="text" name="username" maxlength="10" required></p>'
'<p>Password1: <input type="password" name="password1" required></p>'
'<p>Password2: <input type="password" name="password2" required></p>'
'<input type="submit" required>'
- '</form>',
+ "</form>",
)
- f = UserRegistration(auto_id='id_%s')
+ f = UserRegistration(auto_id="id_%s")
self.assertHTMLEqual(
- t.render(Context({'form': f})),
- '<form>'
+ t.render(Context({"form": f})),
+ "<form>"
'<p><label for="id_username">Username:</label>'
'<input id="id_username" type="text" name="username" maxlength="10" '
- 'required></p>'
+ "required></p>"
'<p><label for="id_password1">Password1:</label>'
'<input type="password" name="password1" id="id_password1" required></p>'
'<p><label for="id_password2">Password2:</label>'
'<input type="password" name="password2" id="id_password2" required></p>'
'<input type="submit" required>'
- '</form>',
+ "</form>",
)
# Use form.[field].legend_tag to output a field's label with a <legend>
# tag wrapped around it, but *only* if the given field has an "id"
# attribute. Recall from above that passing the "auto_id" argument to a
# Form gives each field an "id" attribute.
t = Template(
- '<form>'
- '<p>{{ form.username.legend_tag }} {{ form.username }}</p>'
- '<p>{{ form.password1.legend_tag }} {{ form.password1 }}</p>'
- '<p>{{ form.password2.legend_tag }} {{ form.password2 }}</p>'
+ "<form>"
+ "<p>{{ form.username.legend_tag }} {{ form.username }}</p>"
+ "<p>{{ form.password1.legend_tag }} {{ form.password1 }}</p>"
+ "<p>{{ form.password2.legend_tag }} {{ form.password2 }}</p>"
'<input type="submit" required>'
- '</form>'
+ "</form>"
)
f = UserRegistration(auto_id=False)
self.assertHTMLEqual(
- t.render(Context({'form': f})),
- '<form>'
- '<p>Username: '
+ t.render(Context({"form": f})),
+ "<form>"
+ "<p>Username: "
'<input type="text" name="username" maxlength="10" required></p>'
'<p>Password1: <input type="password" name="password1" required></p>'
'<p>Password2: <input type="password" name="password2" required></p>'
'<input type="submit" required>'
- '</form>',
+ "</form>",
)
- f = UserRegistration(auto_id='id_%s')
+ f = UserRegistration(auto_id="id_%s")
self.assertHTMLEqual(
- t.render(Context({'form': f})),
- '<form>'
+ t.render(Context({"form": f})),
+ "<form>"
'<p><legend for="id_username">Username:</legend>'
'<input id="id_username" type="text" name="username" maxlength="10" '
- 'required></p>'
+ "required></p>"
'<p><legend for="id_password1">Password1:</legend>'
'<input type="password" name="password1" id="id_password1" required></p>'
'<p><legend for="id_password2">Password2:</legend>'
'<input type="password" name="password2" id="id_password2" required></p>'
'<input type="submit" required>'
- '</form>',
+ "</form>",
)
# Use form.[field].help_text to output a field's help text. If the
# given field does not have help text, nothing will be output.
t = Template(
- '<form>'
- '<p>{{ form.username.label_tag }} {{ form.username }}<br>'
- '{{ form.username.help_text }}</p>'
- '<p>{{ form.password1.label_tag }} {{ form.password1 }}</p>'
- '<p>{{ form.password2.label_tag }} {{ form.password2 }}</p>'
+ "<form>"
+ "<p>{{ form.username.label_tag }} {{ form.username }}<br>"
+ "{{ form.username.help_text }}</p>"
+ "<p>{{ form.password1.label_tag }} {{ form.password1 }}</p>"
+ "<p>{{ form.password2.label_tag }} {{ form.password2 }}</p>"
'<input type="submit" required>'
- '</form>'
+ "</form>"
)
f = UserRegistration(auto_id=False)
self.assertHTMLEqual(
- t.render(Context({'form': f})),
- '<form>'
- '<p>Username: '
+ t.render(Context({"form": f})),
+ "<form>"
+ "<p>Username: "
'<input type="text" name="username" maxlength="10" required><br>'
- 'Good luck picking a username that doesn&#x27;t already exist.</p>'
+ "Good luck picking a username that doesn&#x27;t already exist.</p>"
'<p>Password1: <input type="password" name="password1" required></p>'
'<p>Password2: <input type="password" name="password2" required></p>'
'<input type="submit" required>'
- '</form>',
+ "</form>",
)
self.assertEqual(
- Template('{{ form.password1.help_text }}').render(Context({'form': f})),
- '',
+ Template("{{ form.password1.help_text }}").render(Context({"form": f})),
+ "",
)
# To display the errors that aren't associated with a particular field
# e.g. the errors caused by Form.clean() -- use
@@ -3970,59 +4428,59 @@ class TemplateTests(SimpleTestCase):
# is displayed as a <ul> (or an empty string, if the list of errors is
# empty).
t = Template(
- '<form>'
- '{{ form.username.errors.as_ul }}'
- '<p><label>Your username: {{ form.username }}</label></p>'
- '{{ form.password1.errors.as_ul }}'
- '<p><label>Password: {{ form.password1 }}</label></p>'
- '{{ form.password2.errors.as_ul }}'
- '<p><label>Password (again): {{ form.password2 }}</label></p>'
+ "<form>"
+ "{{ form.username.errors.as_ul }}"
+ "<p><label>Your username: {{ form.username }}</label></p>"
+ "{{ form.password1.errors.as_ul }}"
+ "<p><label>Password: {{ form.password1 }}</label></p>"
+ "{{ form.password2.errors.as_ul }}"
+ "<p><label>Password (again): {{ form.password2 }}</label></p>"
'<input type="submit" required>'
- '</form>'
+ "</form>"
)
f = UserRegistration(
- {'username': 'django', 'password1': 'foo', 'password2': 'bar'},
+ {"username": "django", "password1": "foo", "password2": "bar"},
auto_id=False,
)
self.assertHTMLEqual(
- t.render(Context({'form': f})),
- '<form>'
- '<p><label>Your username: '
+ t.render(Context({"form": f})),
+ "<form>"
+ "<p><label>Your username: "
'<input type="text" name="username" value="django" maxlength="10" required>'
- '</label></p>'
- '<p><label>Password: '
+ "</label></p>"
+ "<p><label>Password: "
'<input type="password" name="password1" required></label></p>'
- '<p><label>Password (again): '
+ "<p><label>Password (again): "
'<input type="password" name="password2" required></label></p>'
'<input type="submit" required>'
- '</form>',
+ "</form>",
)
t = Template(
- '<form>'
- '{{ form.non_field_errors }}'
- '{{ form.username.errors.as_ul }}'
- '<p><label>Your username: {{ form.username }}</label></p>'
- '{{ form.password1.errors.as_ul }}'
- '<p><label>Password: {{ form.password1 }}</label></p>'
- '{{ form.password2.errors.as_ul }}'
- '<p><label>Password (again): {{ form.password2 }}</label></p>'
+ "<form>"
+ "{{ form.non_field_errors }}"
+ "{{ form.username.errors.as_ul }}"
+ "<p><label>Your username: {{ form.username }}</label></p>"
+ "{{ form.password1.errors.as_ul }}"
+ "<p><label>Password: {{ form.password1 }}</label></p>"
+ "{{ form.password2.errors.as_ul }}"
+ "<p><label>Password (again): {{ form.password2 }}</label></p>"
'<input type="submit" required>'
- '</form>'
+ "</form>"
)
self.assertHTMLEqual(
- t.render(Context({'form': f})),
- '<form>'
+ t.render(Context({"form": f})),
+ "<form>"
'<ul class="errorlist nonfield">'
- '<li>Please make sure your passwords match.</li></ul>'
- '<p><label>Your username: '
+ "<li>Please make sure your passwords match.</li></ul>"
+ "<p><label>Your username: "
'<input type="text" name="username" value="django" maxlength="10" required>'
- '</label></p>'
- '<p><label>Password: '
+ "</label></p>"
+ "<p><label>Password: "
'<input type="password" name="password1" required></label></p>'
- '<p><label>Password (again): '
+ "<p><label>Password (again): "
'<input type="password" name="password2" required></label></p>'
'<input type="submit" required>'
- '</form>',
+ "</form>",
)
def test_basic_processing_in_view(self):
@@ -4033,77 +4491,83 @@ class TemplateTests(SimpleTestCase):
def clean(self):
if (
- self.cleaned_data.get('password1') and
- self.cleaned_data.get('password2') and
- self.cleaned_data['password1'] != self.cleaned_data['password2']
+ self.cleaned_data.get("password1")
+ and self.cleaned_data.get("password2")
+ and self.cleaned_data["password1"] != self.cleaned_data["password2"]
):
- raise ValidationError('Please make sure your passwords match.')
+ raise ValidationError("Please make sure your passwords match.")
return self.cleaned_data
def my_function(method, post_data):
- if method == 'POST':
+ if method == "POST":
form = UserRegistration(post_data, auto_id=False)
else:
form = UserRegistration(auto_id=False)
if form.is_valid():
- return 'VALID: %r' % sorted(form.cleaned_data.items())
+ return "VALID: %r" % sorted(form.cleaned_data.items())
t = Template(
'<form method="post">'
- '<table>'
- '{{ form }}'
- '</table>'
+ "<table>"
+ "{{ form }}"
+ "</table>"
'<input type="submit" required>'
- '</form>'
+ "</form>"
)
- return t.render(Context({'form': form}))
+ return t.render(Context({"form": form}))
# GET with an empty form and no errors.
self.assertHTMLEqual(
- my_function('GET', {}),
+ my_function("GET", {}),
'<form method="post">'
- '<table>'
- '<tr><th>Username:</th><td>'
+ "<table>"
+ "<tr><th>Username:</th><td>"
'<input type="text" name="username" maxlength="10" required></td></tr>'
- '<tr><th>Password1:</th><td>'
+ "<tr><th>Password1:</th><td>"
'<input type="password" name="password1" required></td></tr>'
- '<tr><th>Password2:</th><td>'
+ "<tr><th>Password2:</th><td>"
'<input type="password" name="password2" required></td></tr>'
- '</table>'
+ "</table>"
'<input type="submit" required>'
- '</form>',
+ "</form>",
)
# POST with erroneous data, a redisplayed form, with errors.
self.assertHTMLEqual(
- my_function('POST', {
- 'username': 'this-is-a-long-username',
- 'password1': 'foo',
- 'password2': 'bar',
- }),
+ my_function(
+ "POST",
+ {
+ "username": "this-is-a-long-username",
+ "password1": "foo",
+ "password2": "bar",
+ },
+ ),
'<form method="post">'
- '<table>'
+ "<table>"
'<tr><td colspan="2"><ul class="errorlist nonfield">'
- '<li>Please make sure your passwords match.</li></ul></td></tr>'
+ "<li>Please make sure your passwords match.</li></ul></td></tr>"
'<tr><th>Username:</th><td><ul class="errorlist">'
- '<li>Ensure this value has at most 10 characters (it has 23).</li></ul>'
+ "<li>Ensure this value has at most 10 characters (it has 23).</li></ul>"
'<input type="text" name="username" '
'value="this-is-a-long-username" maxlength="10" required></td></tr>'
- '<tr><th>Password1:</th><td>'
+ "<tr><th>Password1:</th><td>"
'<input type="password" name="password1" required></td></tr>'
- '<tr><th>Password2:</th><td>'
+ "<tr><th>Password2:</th><td>"
'<input type="password" name="password2" required></td></tr>'
- '</table>'
+ "</table>"
'<input type="submit" required>'
- '</form>',
+ "</form>",
)
# POST with valid data (the success message).
self.assertEqual(
- my_function('POST', {
- 'username': 'adrian',
- 'password1': 'secret',
- 'password2': 'secret',
- }),
+ my_function(
+ "POST",
+ {
+ "username": "adrian",
+ "password1": "secret",
+ "password2": "secret",
+ },
+ ),
"VALID: [('password1', 'secret'), ('password2', 'secret'), "
"('username', 'adrian')]",
)
@@ -4113,10 +4577,10 @@ class OverrideTests(SimpleTestCase):
def test_use_custom_template(self):
class Person(Form):
first_name = CharField()
- template_name = 'forms_tests/form_snippet.html'
+ template_name = "forms_tests/form_snippet.html"
- t = Template('{{ form }}')
- html = t.render(Context({'form': Person()}))
+ t = Template("{{ form }}")
+ html = t.render(Context({"form": Person()}))
expected = """
<div class="fieldWrapper"><label for="id_first_name">First name:</label>
<input type="text" name="first_name" required id="id_first_name"></div>
@@ -4125,14 +4589,14 @@ class OverrideTests(SimpleTestCase):
def test_errorlist_override(self):
class CustomErrorList(ErrorList):
- template_name = 'forms_tests/error.html'
+ template_name = "forms_tests/error.html"
class CommentForm(Form):
name = CharField(max_length=50, required=False)
email = EmailField()
comment = CharField()
- data = {'email': 'invalid'}
+ data = {"email": "invalid"}
f = CommentForm(data, auto_id=False, error_class=CustomErrorList)
self.assertHTMLEqual(
f.as_p(),
@@ -4148,18 +4612,18 @@ class OverrideTests(SimpleTestCase):
def test_cyclic_context_boundfield_render(self):
class FirstNameForm(Form):
first_name = CharField()
- template_name_label = 'forms_tests/cyclic_context_boundfield_render.html'
+ template_name_label = "forms_tests/cyclic_context_boundfield_render.html"
f = FirstNameForm()
try:
- self.assertInHTML('<th>1</th>', f.render())
+ self.assertInHTML("<th>1</th>", f.render())
except RecursionError:
- self.fail('Cyclic reference in BoundField.render().')
+ self.fail("Cyclic reference in BoundField.render().")
def test_legend_tag(self):
class CustomFrameworkForm(FrameworkForm):
- template_name = 'forms_tests/legend_test.html'
- required_css_class = 'required'
+ template_name = "forms_tests/legend_test.html"
+ required_css_class = "required"
f = CustomFrameworkForm()
self.assertHTMLEqual(
diff --git a/tests/forms_tests/tests/test_formsets.py b/tests/forms_tests/tests/test_formsets.py
index c5a4f259e0..9846cb5874 100644
--- a/tests/forms_tests/tests/test_formsets.py
+++ b/tests/forms_tests/tests/test_formsets.py
@@ -4,12 +4,24 @@ from unittest import mock
from django.core.exceptions import ValidationError
from django.forms import (
- BaseForm, CharField, DateField, FileField, Form, IntegerField,
- SplitDateTimeField, formsets,
+ BaseForm,
+ CharField,
+ DateField,
+ FileField,
+ Form,
+ IntegerField,
+ SplitDateTimeField,
+ formsets,
)
from django.forms.formsets import (
- INITIAL_FORM_COUNT, MAX_NUM_FORM_COUNT, MIN_NUM_FORM_COUNT,
- TOTAL_FORM_COUNT, BaseFormSet, ManagementForm, all_valid, formset_factory,
+ INITIAL_FORM_COUNT,
+ MAX_NUM_FORM_COUNT,
+ MIN_NUM_FORM_COUNT,
+ TOTAL_FORM_COUNT,
+ BaseFormSet,
+ ManagementForm,
+ all_valid,
+ formset_factory,
)
from django.forms.utils import ErrorList
from django.forms.widgets import HiddenInput
@@ -29,7 +41,7 @@ ChoiceFormSet = formset_factory(Choice)
class ChoiceFormsetWithNonFormError(ChoiceFormSet):
def clean(self):
super().clean()
- raise ValidationError('non-form error')
+ raise ValidationError("non-form error")
class FavoriteDrinkForm(Form):
@@ -41,15 +53,17 @@ class BaseFavoriteDrinksFormSet(BaseFormSet):
seen_drinks = []
for drink in self.cleaned_data:
- if drink['name'] in seen_drinks:
- raise ValidationError('You may only specify a drink once.')
+ if drink["name"] in seen_drinks:
+ raise ValidationError("You may only specify a drink once.")
- seen_drinks.append(drink['name'])
+ seen_drinks.append(drink["name"])
# A FormSet that takes a list of favorite drinks and raises an error if
# there are any duplicates.
-FavoriteDrinksFormSet = formset_factory(FavoriteDrinkForm, formset=BaseFavoriteDrinksFormSet, extra=3)
+FavoriteDrinksFormSet = formset_factory(
+ FavoriteDrinkForm, formset=BaseFavoriteDrinksFormSet, extra=3
+)
class CustomKwargForm(Form):
@@ -59,16 +73,22 @@ class CustomKwargForm(Form):
class FormsFormsetTestCase(SimpleTestCase):
-
def make_choiceformset(
- self, formset_data=None, formset_class=ChoiceFormSet,
- total_forms=None, initial_forms=0, max_num_forms=0, min_num_forms=0, **kwargs):
+ self,
+ formset_data=None,
+ formset_class=ChoiceFormSet,
+ 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.
"""
- kwargs.setdefault('prefix', 'choices')
- kwargs.setdefault('auto_id', False)
+ kwargs.setdefault("prefix", "choices")
+ kwargs.setdefault("auto_id", False)
if formset_data is None:
return formset_class(**kwargs)
@@ -77,18 +97,18 @@ class FormsFormsetTestCase(SimpleTestCase):
total_forms = len(formset_data)
def prefixed(*args):
- args = (kwargs['prefix'],) + args
- return '-'.join(args)
+ args = (kwargs["prefix"],) + args
+ return "-".join(args)
data = {
- 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),
+ 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
- data[prefixed(str(i), 'votes')] = votes
+ data[prefixed(str(i), "choice")] = choice
+ data[prefixed(str(i), "votes")] = votes
return formset_class(data, **kwargs)
@@ -105,15 +125,18 @@ class FormsFormsetTestCase(SimpleTestCase):
<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>"""
+<tr><th>Votes:</th><td><input type="number" name="choices-0-votes"></td></tr>""",
)
# FormSet are treated similarly to Forms. 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, cleaned_data
# and errors will be a list of dicts rather than a single dict.
- formset = self.make_choiceformset([('Calexico', '100')])
+ formset = self.make_choiceformset([("Calexico", "100")])
self.assertTrue(formset.is_valid())
- self.assertEqual([form.cleaned_data for form in formset.forms], [{'votes': 100, 'choice': 'Calexico'}])
+ self.assertEqual(
+ [form.cleaned_data for form in formset.forms],
+ [{"votes": 100, "choice": "Calexico"}],
+ )
# If a FormSet wasn't passed any data, is_valid() and has_changed()
# return False.
@@ -127,41 +150,45 @@ class FormsFormsetTestCase(SimpleTestCase):
underlying forms.
"""
FormSet = formset_factory(CustomKwargForm, extra=2)
- formset = FormSet(form_kwargs={'custom_kwarg': 1})
+ formset = FormSet(form_kwargs={"custom_kwarg": 1})
for form in formset:
- self.assertTrue(hasattr(form, 'custom_kwarg'))
+ self.assertTrue(hasattr(form, "custom_kwarg"))
self.assertEqual(form.custom_kwarg, 1)
def test_form_kwargs_formset_dynamic(self):
"""Form kwargs can be passed dynamically in a formset."""
+
class DynamicBaseFormSet(BaseFormSet):
def get_form_kwargs(self, index):
- return {'custom_kwarg': index}
+ return {"custom_kwarg": index}
- DynamicFormSet = formset_factory(CustomKwargForm, formset=DynamicBaseFormSet, extra=2)
- formset = DynamicFormSet(form_kwargs={'custom_kwarg': 'ignored'})
+ DynamicFormSet = formset_factory(
+ CustomKwargForm, formset=DynamicBaseFormSet, extra=2
+ )
+ formset = DynamicFormSet(form_kwargs={"custom_kwarg": "ignored"})
for i, form in enumerate(formset):
- self.assertTrue(hasattr(form, 'custom_kwarg'))
+ self.assertTrue(hasattr(form, "custom_kwarg"))
self.assertEqual(form.custom_kwarg, i)
def test_form_kwargs_empty_form(self):
FormSet = formset_factory(CustomKwargForm)
- formset = FormSet(form_kwargs={'custom_kwarg': 1})
- self.assertTrue(hasattr(formset.empty_form, 'custom_kwarg'))
+ formset = FormSet(form_kwargs={"custom_kwarg": 1})
+ self.assertTrue(hasattr(formset.empty_form, "custom_kwarg"))
self.assertEqual(formset.empty_form.custom_kwarg, 1)
def test_formset_validation(self):
# FormSet instances can also have an error attribute if validation failed for
# any of the forms.
- formset = self.make_choiceformset([('Calexico', '')])
+ formset = self.make_choiceformset([("Calexico", "")])
self.assertFalse(formset.is_valid())
- self.assertEqual(formset.errors, [{'votes': ['This field is required.']}])
+ self.assertEqual(formset.errors, [{"votes": ["This field is required."]}])
def test_formset_validation_count(self):
"""
A formset's ManagementForm is validated once per FormSet.is_valid()
call and each form of the formset is cleaned once.
"""
+
def make_method_counter(func):
"""Add a counter to func for the number of times it's called."""
counter = Counter()
@@ -173,12 +200,17 @@ class FormsFormsetTestCase(SimpleTestCase):
return mocked_func, counter
- mocked_is_valid, is_valid_counter = make_method_counter(formsets.ManagementForm.is_valid)
+ mocked_is_valid, is_valid_counter = make_method_counter(
+ formsets.ManagementForm.is_valid
+ )
mocked_full_clean, full_clean_counter = make_method_counter(BaseForm.full_clean)
- formset = self.make_choiceformset([('Calexico', '100'), ('Any1', '42'), ('Any2', '101')])
+ formset = self.make_choiceformset(
+ [("Calexico", "100"), ("Any1", "42"), ("Any2", "101")]
+ )
- with mock.patch('django.forms.formsets.ManagementForm.is_valid', mocked_is_valid), \
- mock.patch('django.forms.forms.BaseForm.full_clean', mocked_full_clean):
+ with mock.patch(
+ "django.forms.formsets.ManagementForm.is_valid", mocked_is_valid
+ ), mock.patch("django.forms.forms.BaseForm.full_clean", mocked_full_clean):
self.assertTrue(formset.is_valid())
self.assertEqual(is_valid_counter.call_count, 1)
self.assertEqual(full_clean_counter.call_count, 4)
@@ -188,14 +220,14 @@ class FormsFormsetTestCase(SimpleTestCase):
FormSet.has_changed() is True if any data is passed to its forms, even
if the formset didn't validate.
"""
- blank_formset = self.make_choiceformset([('', '')])
+ blank_formset = self.make_choiceformset([("", "")])
self.assertFalse(blank_formset.has_changed())
# invalid formset
- invalid_formset = self.make_choiceformset([('Calexico', '')])
+ invalid_formset = self.make_choiceformset([("Calexico", "")])
self.assertFalse(invalid_formset.is_valid())
self.assertTrue(invalid_formset.has_changed())
# valid formset
- valid_formset = self.make_choiceformset([('Calexico', '100')])
+ valid_formset = self.make_choiceformset([("Calexico", "100")])
self.assertTrue(valid_formset.is_valid())
self.assertTrue(valid_formset.has_changed())
@@ -205,40 +237,55 @@ class FormsFormsetTestCase(SimpleTestCase):
dicts to the `initial` argument. By default, an extra blank form is
included.
"""
- formset = self.make_choiceformset(initial=[{'choice': 'Calexico', 'votes': 100}])
+ formset = self.make_choiceformset(
+ initial=[{"choice": "Calexico", "votes": 100}]
+ )
self.assertHTMLEqual(
- '\n'.join(form.as_ul() for form in formset.forms),
+ "\n".join(form.as_ul() for form in formset.forms),
"""<li>Choice: <input type="text" name="choices-0-choice" value="Calexico"></li>
<li>Votes: <input type="number" name="choices-0-votes" value="100"></li>
<li>Choice: <input type="text" name="choices-1-choice"></li>
-<li>Votes: <input type="number" name="choices-1-votes"></li>"""
+<li>Votes: <input type="number" name="choices-1-votes"></li>""",
)
def test_blank_form_unfilled(self):
"""A form that's displayed as blank may be submitted as blank."""
- formset = self.make_choiceformset([('Calexico', '100'), ('', '')], initial_forms=1)
+ formset = self.make_choiceformset(
+ [("Calexico", "100"), ("", "")], initial_forms=1
+ )
self.assertTrue(formset.is_valid())
- self.assertEqual([form.cleaned_data for form in formset.forms], [{'votes': 100, 'choice': 'Calexico'}, {}])
+ self.assertEqual(
+ [form.cleaned_data for form in formset.forms],
+ [{"votes": 100, "choice": "Calexico"}, {}],
+ )
def test_second_form_partially_filled(self):
"""
If at least one field is filled out on a blank form, it will be
validated.
"""
- formset = self.make_choiceformset([('Calexico', '100'), ('The Decemberists', '')], initial_forms=1)
+ formset = self.make_choiceformset(
+ [("Calexico", "100"), ("The Decemberists", "")], initial_forms=1
+ )
self.assertFalse(formset.is_valid())
- self.assertEqual(formset.errors, [{}, {'votes': ['This field is required.']}])
+ self.assertEqual(formset.errors, [{}, {"votes": ["This field is required."]}])
def test_delete_prefilled_data(self):
"""
Deleting prefilled data is an error. Removing data from form fields
isn't the proper way to delete it.
"""
- formset = self.make_choiceformset([('', ''), ('', '')], initial_forms=1)
+ formset = self.make_choiceformset([("", ""), ("", "")], initial_forms=1)
self.assertFalse(formset.is_valid())
self.assertEqual(
formset.errors,
- [{'votes': ['This field is required.'], 'choice': ['This field is required.']}, {}]
+ [
+ {
+ "votes": ["This field is required."],
+ "choice": ["This field is required."],
+ },
+ {},
+ ],
)
def test_displaying_more_than_one_blank_form(self):
@@ -247,32 +294,32 @@ class FormsFormsetTestCase(SimpleTestCase):
`extra` argument.
"""
ChoiceFormSet = formset_factory(Choice, extra=3)
- formset = ChoiceFormSet(auto_id=False, prefix='choices')
+ formset = ChoiceFormSet(auto_id=False, prefix="choices")
self.assertHTMLEqual(
- '\n'.join(form.as_ul() for form in formset.forms),
+ "\n".join(form.as_ul() for form in formset.forms),
"""<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>"""
+<li>Votes: <input type="number" name="choices-2-votes"></li>""",
)
# Since every form was displayed as blank, they are also accepted as
# blank. This may seem a little strange, but min_num is used 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-MIN_NUM_FORMS': '0', # min number of forms
- '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': '',
+ "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": "",
+ "choices-1-choice": "",
+ "choices-1-votes": "",
+ "choices-2-choice": "",
+ "choices-2-votes": "",
}
- formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
+ formset = ChoiceFormSet(data, auto_id=False, prefix="choices")
self.assertTrue(formset.is_valid())
self.assertEqual([form.cleaned_data for form in formset.forms], [{}, {}, {}])
@@ -282,50 +329,53 @@ class FormsFormsetTestCase(SimpleTestCase):
min_num argument. It will (essentially) increment the extra argument.
"""
ChoiceFormSet = formset_factory(Choice, extra=1, min_num=1)
- formset = ChoiceFormSet(auto_id=False, prefix='choices')
+ formset = ChoiceFormSet(auto_id=False, prefix="choices")
# Min_num forms are required; extra forms can be empty.
self.assertFalse(formset.forms[0].empty_permitted)
self.assertTrue(formset.forms[1].empty_permitted)
self.assertHTMLEqual(
- '\n'.join(form.as_ul() for form in formset.forms),
+ "\n".join(form.as_ul() for form in formset.forms),
"""<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>Votes: <input type="number" name="choices-1-votes"></li>""",
)
def test_min_num_displaying_more_than_one_blank_form_with_zero_extra(self):
"""More than 1 empty form can be displayed using min_num."""
ChoiceFormSet = formset_factory(Choice, extra=0, min_num=3)
- formset = ChoiceFormSet(auto_id=False, prefix='choices')
+ formset = ChoiceFormSet(auto_id=False, prefix="choices")
self.assertHTMLEqual(
- '\n'.join(form.as_ul() for form in formset.forms),
+ "\n".join(form.as_ul() for form in formset.forms),
"""<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>"""
+<li>Votes: <input type="number" name="choices-2-votes"></li>""",
)
def test_single_form_completed(self):
"""Just one form may be completed."""
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',
- 'choices-1-choice': '',
- 'choices-1-votes': '',
- 'choices-2-choice': '',
- 'choices-2-votes': '',
+ "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",
+ "choices-1-choice": "",
+ "choices-1-votes": "",
+ "choices-2-choice": "",
+ "choices-2-votes": "",
}
ChoiceFormSet = formset_factory(Choice, extra=3)
- formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
+ formset = ChoiceFormSet(data, auto_id=False, prefix="choices")
self.assertTrue(formset.is_valid())
- self.assertEqual([form.cleaned_data for form in formset.forms], [{'votes': 100, 'choice': 'Calexico'}, {}, {}])
+ self.assertEqual(
+ [form.cleaned_data for form in formset.forms],
+ [{"votes": 100, "choice": "Calexico"}, {}, {}],
+ )
def test_formset_validate_max_flag(self):
"""
@@ -335,19 +385,19 @@ class FormsFormsetTestCase(SimpleTestCase):
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': '2', # max number of forms - should be ignored
- 'choices-0-choice': 'Zero',
- 'choices-0-votes': '0',
- 'choices-1-choice': 'One',
- 'choices-1-votes': '1',
+ "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",
+ "choices-1-choice": "One",
+ "choices-1-votes": "1",
}
ChoiceFormSet = formset_factory(Choice, extra=1, max_num=1, validate_max=True)
- formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
+ formset = ChoiceFormSet(data, auto_id=False, prefix="choices")
self.assertFalse(formset.is_valid())
- self.assertEqual(formset.non_form_errors(), ['Please submit at most 1 form.'])
+ self.assertEqual(formset.non_form_errors(), ["Please submit at most 1 form."])
self.assertEqual(
str(formset.non_form_errors()),
'<ul class="errorlist nonform"><li>Please submit at most 1 form.</li></ul>',
@@ -361,23 +411,23 @@ class FormsFormsetTestCase(SimpleTestCase):
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',
+ "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')
+ formset = ChoiceFormSet(data, auto_id=False, prefix="choices")
self.assertFalse(formset.is_valid())
- self.assertEqual(formset.non_form_errors(), ['Please submit at least 3 forms.'])
+ self.assertEqual(formset.non_form_errors(), ["Please submit at least 3 forms."])
self.assertEqual(
str(formset.non_form_errors()),
'<ul class="errorlist nonform"><li>'
- 'Please submit at least 3 forms.</li></ul>',
+ "Please submit at least 3 forms.</li></ul>",
)
def test_formset_validate_min_unchanged_forms(self):
@@ -386,65 +436,69 @@ class FormsFormsetTestCase(SimpleTestCase):
as "empty".
"""
initial = [
- {'choice': 'Zero', 'votes': 0},
- {'choice': 'One', 'votes': 0},
+ {"choice": "Zero", "votes": 0},
+ {"choice": "One", "votes": 0},
]
data = {
- 'choices-TOTAL_FORMS': '2',
- 'choices-INITIAL_FORMS': '2',
- 'choices-MIN_NUM_FORMS': '0',
- 'choices-MAX_NUM_FORMS': '2',
- 'choices-0-choice': 'Zero',
- 'choices-0-votes': '0',
- 'choices-1-choice': 'One',
- 'choices-1-votes': '1', # changed from initial
+ "choices-TOTAL_FORMS": "2",
+ "choices-INITIAL_FORMS": "2",
+ "choices-MIN_NUM_FORMS": "0",
+ "choices-MAX_NUM_FORMS": "2",
+ "choices-0-choice": "Zero",
+ "choices-0-votes": "0",
+ "choices-1-choice": "One",
+ "choices-1-votes": "1", # changed from initial
}
ChoiceFormSet = formset_factory(Choice, min_num=2, validate_min=True)
- formset = ChoiceFormSet(data, auto_id=False, prefix='choices', initial=initial)
+ formset = ChoiceFormSet(data, auto_id=False, prefix="choices", initial=initial)
self.assertFalse(formset.forms[0].has_changed())
self.assertTrue(formset.forms[1].has_changed())
self.assertTrue(formset.is_valid())
def test_formset_validate_min_excludes_empty_forms(self):
data = {
- 'choices-TOTAL_FORMS': '2',
- 'choices-INITIAL_FORMS': '0',
+ "choices-TOTAL_FORMS": "2",
+ "choices-INITIAL_FORMS": "0",
}
- ChoiceFormSet = formset_factory(Choice, extra=2, min_num=1, validate_min=True, can_delete=True)
- formset = ChoiceFormSet(data, prefix='choices')
+ ChoiceFormSet = formset_factory(
+ Choice, extra=2, min_num=1, validate_min=True, can_delete=True
+ )
+ formset = ChoiceFormSet(data, prefix="choices")
self.assertFalse(formset.has_changed())
self.assertFalse(formset.is_valid())
- self.assertEqual(formset.non_form_errors(), ['Please submit at least 1 form.'])
+ 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."""
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',
- 'choices-1-choice': 'The Decemberists',
- 'choices-1-votes': '', # missing value
- 'choices-2-choice': '',
- 'choices-2-votes': '',
+ "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",
+ "choices-1-choice": "The Decemberists",
+ "choices-1-votes": "", # missing value
+ "choices-2-choice": "",
+ "choices-2-votes": "",
}
ChoiceFormSet = formset_factory(Choice, extra=3)
- formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
+ formset = ChoiceFormSet(data, auto_id=False, prefix="choices")
self.assertFalse(formset.is_valid())
- self.assertEqual(formset.errors, [{}, {'votes': ['This field is required.']}, {}])
+ self.assertEqual(
+ formset.errors, [{}, {"votes": ["This field is required."]}, {}]
+ )
def test_more_initial_data(self):
"""
The extra argument works when the formset is pre-filled with initial
data.
"""
- initial = [{'choice': 'Calexico', 'votes': 100}]
+ initial = [{"choice": "Calexico", "votes": 100}]
ChoiceFormSet = formset_factory(Choice, extra=3)
- formset = ChoiceFormSet(initial=initial, auto_id=False, prefix='choices')
+ formset = ChoiceFormSet(initial=initial, auto_id=False, prefix="choices")
self.assertHTMLEqual(
- '\n'.join(form.as_ul() for form in formset.forms),
+ "\n".join(form.as_ul() for form in formset.forms),
"""<li>Choice: <input type="text" name="choices-0-choice" value="Calexico"></li>
<li>Votes: <input type="number" name="choices-0-votes" value="100"></li>
<li>Choice: <input type="text" name="choices-1-choice"></li>
@@ -452,14 +506,14 @@ class FormsFormsetTestCase(SimpleTestCase):
<li>Choice: <input type="text" name="choices-2-choice"></li>
<li>Votes: <input type="number" name="choices-2-votes"></li>
<li>Choice: <input type="text" name="choices-3-choice"></li>
-<li>Votes: <input type="number" name="choices-3-votes"></li>"""
+<li>Votes: <input type="number" name="choices-3-votes"></li>""",
)
# Retrieving an empty form works. Tt shows up in the form list.
self.assertTrue(formset.empty_form.empty_permitted)
self.assertHTMLEqual(
formset.empty_form.as_ul(),
"""<li>Choice: <input type="text" name="choices-__prefix__-choice"></li>
-<li>Votes: <input type="number" name="choices-__prefix__-votes"></li>"""
+<li>Votes: <input type="number" name="choices-__prefix__-votes"></li>""",
)
def test_formset_with_deletion(self):
@@ -469,10 +523,13 @@ class FormsFormsetTestCase(SimpleTestCase):
formset.deleted_forms.
"""
ChoiceFormSet = formset_factory(Choice, can_delete=True)
- initial = [{'choice': 'Calexico', 'votes': 100}, {'choice': 'Fergie', 'votes': 900}]
- formset = ChoiceFormSet(initial=initial, auto_id=False, prefix='choices')
+ initial = [
+ {"choice": "Calexico", "votes": 100},
+ {"choice": "Fergie", "votes": 900},
+ ]
+ formset = ChoiceFormSet(initial=initial, auto_id=False, prefix="choices")
self.assertHTMLEqual(
- '\n'.join(form.as_ul() for form in formset.forms),
+ "\n".join(form.as_ul() for form in formset.forms),
"""<li>Choice: <input type="text" name="choices-0-choice" value="Calexico"></li>
<li>Votes: <input type="number" name="choices-0-votes" value="100"></li>
<li>Delete: <input type="checkbox" name="choices-0-DELETE"></li>
@@ -481,38 +538,38 @@ class FormsFormsetTestCase(SimpleTestCase):
<li>Delete: <input type="checkbox" name="choices-1-DELETE"></li>
<li>Choice: <input type="text" name="choices-2-choice"></li>
<li>Votes: <input type="number" name="choices-2-votes"></li>
-<li>Delete: <input type="checkbox" name="choices-2-DELETE"></li>"""
+<li>Delete: <input type="checkbox" name="choices-2-DELETE"></li>""",
)
# To delete something, 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-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',
- 'choices-0-DELETE': '',
- 'choices-1-choice': 'Fergie',
- 'choices-1-votes': '900',
- 'choices-1-DELETE': 'on',
- 'choices-2-choice': '',
- 'choices-2-votes': '',
- 'choices-2-DELETE': '',
+ "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",
+ "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 = ChoiceFormSet(data, auto_id=False, prefix="choices")
self.assertTrue(formset.is_valid())
self.assertEqual(
[form.cleaned_data for form in formset.forms],
[
- {'votes': 100, 'DELETE': False, 'choice': 'Calexico'},
- {'votes': 900, 'DELETE': True, 'choice': 'Fergie'},
+ {"votes": 100, "DELETE": False, "choice": "Calexico"},
+ {"votes": 900, "DELETE": True, "choice": "Fergie"},
{},
- ]
+ ],
)
self.assertEqual(
[form.cleaned_data for form in formset.deleted_forms],
- [{'votes': 900, 'DELETE': True, 'choice': 'Fergie'}]
+ [{"votes": 900, "DELETE": True, "choice": "Fergie"}],
)
def test_formset_with_deletion_remove_deletion_flag(self):
@@ -521,27 +578,28 @@ class FormsFormsetTestCase(SimpleTestCase):
form's errors shouldn't 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
- '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': '',
- 'check-1-field': '50',
- 'check-1-DELETE': 'on',
- 'check-2-field': '',
- 'check-2-DELETE': '',
+ "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": "",
+ "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 = CheckFormSet(data, prefix="check")
self.assertTrue(formset.is_valid())
# If the deletion flag is removed, validation is enabled.
- data['check-1-DELETE'] = ''
- formset = CheckFormSet(data, prefix='check')
+ data["check-1-DELETE"] = ""
+ formset = CheckFormSet(data, prefix="check")
self.assertFalse(formset.is_valid())
def test_formset_with_deletion_invalid_deleted_form(self):
@@ -550,14 +608,16 @@ class FormsFormsetTestCase(SimpleTestCase):
have been invalid.
"""
FavoriteDrinkFormset = formset_factory(form=FavoriteDrinkForm, can_delete=True)
- formset = FavoriteDrinkFormset({
- 'form-0-name': '',
- 'form-0-DELETE': 'on', # no name!
- 'form-TOTAL_FORMS': 1,
- 'form-INITIAL_FORMS': 1,
- 'form-MIN_NUM_FORMS': 0,
- 'form-MAX_NUM_FORMS': 1,
- })
+ formset = FavoriteDrinkFormset(
+ {
+ "form-0-name": "",
+ "form-0-DELETE": "on", # no name!
+ "form-TOTAL_FORMS": 1,
+ "form-INITIAL_FORMS": 1,
+ "form-MIN_NUM_FORMS": 0,
+ "form-MAX_NUM_FORMS": 1,
+ }
+ )
self.assertTrue(formset.is_valid())
self.assertEqual(formset._errors, [])
self.assertEqual(len(formset.deleted_forms), 1)
@@ -568,7 +628,7 @@ class FormsFormsetTestCase(SimpleTestCase):
class DeletionMethodFormSet(BaseFormSet):
def get_deletion_widget(self):
- return HiddenInput(attrs={'class': 'deletion'})
+ return HiddenInput(attrs={"class": "deletion"})
tests = [
(DeletionAttributeFormSet, '<input type="hidden" name="form-0-DELETE">'),
@@ -586,11 +646,11 @@ class FormsFormsetTestCase(SimpleTestCase):
)
formset = ArticleFormSet(auto_id=False)
self.assertHTMLEqual(
- '\n'.join([form.as_ul() for form in formset.forms]),
+ "\n".join([form.as_ul() for form in formset.forms]),
(
f'<li>Title: <input type="text" name="form-0-title"></li>'
f'<li>Pub date: <input type="text" name="form-0-pub_date">'
- f'{delete_html}</li>'
+ f"{delete_html}</li>"
),
)
@@ -605,10 +665,13 @@ class FormsFormsetTestCase(SimpleTestCase):
front of the list, you'd need to set its order to 0.
"""
ChoiceFormSet = formset_factory(Choice, can_order=True)
- initial = [{'choice': 'Calexico', 'votes': 100}, {'choice': 'Fergie', 'votes': 900}]
- formset = ChoiceFormSet(initial=initial, auto_id=False, prefix='choices')
+ initial = [
+ {"choice": "Calexico", "votes": 100},
+ {"choice": "Fergie", "votes": 900},
+ ]
+ formset = ChoiceFormSet(initial=initial, auto_id=False, prefix="choices")
self.assertHTMLEqual(
- '\n'.join(form.as_ul() for form in formset.forms),
+ "\n".join(form.as_ul() for form in formset.forms),
"""<li>Choice: <input type="text" name="choices-0-choice" value="Calexico"></li>
<li>Votes: <input type="number" name="choices-0-votes" value="100"></li>
<li>Order: <input type="number" name="choices-0-ORDER" value="1"></li>
@@ -617,31 +680,31 @@ class FormsFormsetTestCase(SimpleTestCase):
<li>Order: <input type="number" name="choices-1-ORDER" value="2"></li>
<li>Choice: <input type="text" name="choices-2-choice"></li>
<li>Votes: <input type="number" name="choices-2-votes"></li>
-<li>Order: <input type="number" name="choices-2-ORDER"></li>"""
+<li>Order: <input type="number" 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-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',
- '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',
+ "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",
+ "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 = ChoiceFormSet(data, auto_id=False, prefix="choices")
self.assertTrue(formset.is_valid())
self.assertEqual(
[form.cleaned_data for form in formset.ordered_forms],
[
- {'votes': 500, 'ORDER': 0, 'choice': 'The Decemberists'},
- {'votes': 100, 'ORDER': 1, 'choice': 'Calexico'},
- {'votes': 900, 'ORDER': 2, 'choice': 'Fergie'},
+ {"votes": 500, "ORDER": 0, "choice": "The Decemberists"},
+ {"votes": 100, "ORDER": 1, "choice": "Calexico"},
+ {"votes": 900, "ORDER": 2, "choice": "Fergie"},
],
)
@@ -651,22 +714,27 @@ class FormsFormsetTestCase(SimpleTestCase):
class OrderingMethodFormSet(BaseFormSet):
def get_ordering_widget(self):
- return HiddenInput(attrs={'class': 'ordering'})
+ return HiddenInput(attrs={"class": "ordering"})
tests = (
(OrderingAttributeFormSet, '<input type="hidden" name="form-0-ORDER">'),
- (OrderingMethodFormSet, '<input class="ordering" type="hidden" name="form-0-ORDER">'),
+ (
+ OrderingMethodFormSet,
+ '<input class="ordering" type="hidden" name="form-0-ORDER">',
+ ),
)
for formset_class, order_html in tests:
with self.subTest(formset_class=formset_class.__name__):
- ArticleFormSet = formset_factory(ArticleForm, formset=formset_class, can_order=True)
+ ArticleFormSet = formset_factory(
+ ArticleForm, formset=formset_class, can_order=True
+ )
formset = ArticleFormSet(auto_id=False)
self.assertHTMLEqual(
- '\n'.join(form.as_ul() for form in formset.forms),
+ "\n".join(form.as_ul() for form in formset.forms),
(
'<li>Title: <input type="text" name="form-0-title"></li>'
'<li>Pub date: <input type="text" name="form-0-pub_date">'
- '%s</li>' % order_html
+ "%s</li>" % order_html
),
)
@@ -676,46 +744,46 @@ class FormsFormsetTestCase(SimpleTestCase):
they'll 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-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',
- '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': '',
+ "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",
+ "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": "",
}
ChoiceFormSet = formset_factory(Choice, can_order=True)
- formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
+ formset = ChoiceFormSet(data, auto_id=False, prefix="choices")
self.assertTrue(formset.is_valid())
self.assertEqual(
[form.cleaned_data for form in formset.ordered_forms],
[
- {'votes': 100, 'ORDER': 1, 'choice': 'Calexico'},
- {'votes': 900, 'ORDER': 2, 'choice': 'Fergie'},
- {'votes': 500, 'ORDER': None, 'choice': 'The Decemberists'},
- {'votes': 50, 'ORDER': None, 'choice': 'Basia Bulat'},
+ {"votes": 100, "ORDER": 1, "choice": "Calexico"},
+ {"votes": 900, "ORDER": 2, "choice": "Fergie"},
+ {"votes": 500, "ORDER": None, "choice": "The Decemberists"},
+ {"votes": 50, "ORDER": None, "choice": "Basia Bulat"},
],
)
def test_ordering_blank_fieldsets(self):
"""Ordering works 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-MIN_NUM_FORMS': '0', # min number of forms
- 'choices-MAX_NUM_FORMS': '0', # max number of forms
+ "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
}
ChoiceFormSet = formset_factory(Choice, can_order=True)
- formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
+ formset = ChoiceFormSet(data, auto_id=False, prefix="choices")
self.assertTrue(formset.is_valid())
self.assertEqual(formset.ordered_forms, [])
@@ -723,13 +791,13 @@ class FormsFormsetTestCase(SimpleTestCase):
"""FormSets with ordering + deletion."""
ChoiceFormSet = formset_factory(Choice, can_order=True, can_delete=True)
initial = [
- {'choice': 'Calexico', 'votes': 100},
- {'choice': 'Fergie', 'votes': 900},
- {'choice': 'The Decemberists', 'votes': 500},
+ {"choice": "Calexico", "votes": 100},
+ {"choice": "Fergie", "votes": 900},
+ {"choice": "The Decemberists", "votes": 500},
]
- formset = ChoiceFormSet(initial=initial, auto_id=False, prefix='choices')
+ formset = ChoiceFormSet(initial=initial, auto_id=False, prefix="choices")
self.assertHTMLEqual(
- '\n'.join(form.as_ul() for form in formset.forms),
+ "\n".join(form.as_ul() for form in formset.forms),
"""<li>Choice: <input type="text" name="choices-0-choice" value="Calexico"></li>
<li>Votes: <input type="number" name="choices-0-votes" value="100"></li>
<li>Order: <input type="number" name="choices-0-ORDER" value="1"></li>
@@ -745,43 +813,48 @@ class FormsFormsetTestCase(SimpleTestCase):
<li>Choice: <input type="text" name="choices-3-choice"></li>
<li>Votes: <input type="number" name="choices-3-votes"></li>
<li>Order: <input type="number" name="choices-3-ORDER"></li>
-<li>Delete: <input type="checkbox" name="choices-3-DELETE"></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-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',
- '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': '',
+ "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",
+ "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 = ChoiceFormSet(data, auto_id=False, prefix="choices")
self.assertTrue(formset.is_valid())
self.assertEqual(
[form.cleaned_data for form in formset.ordered_forms],
[
- {'votes': 500, 'DELETE': False, 'ORDER': 0, 'choice': 'The Decemberists'},
- {'votes': 100, 'DELETE': False, 'ORDER': 1, 'choice': 'Calexico'},
+ {
+ "votes": 500,
+ "DELETE": False,
+ "ORDER": 0,
+ "choice": "The Decemberists",
+ },
+ {"votes": 100, "DELETE": False, "ORDER": 1, "choice": "Calexico"},
],
)
self.assertEqual(
[form.cleaned_data for form in formset.deleted_forms],
- [{'votes': 900, 'DELETE': True, 'ORDER': 2, 'choice': 'Fergie'}]
+ [{"votes": 900, "DELETE": True, "ORDER": 2, "choice": "Fergie"}],
)
def test_invalid_deleted_form_with_ordering(self):
@@ -789,15 +862,19 @@ class FormsFormsetTestCase(SimpleTestCase):
Can get ordered_forms from a valid formset even if a deleted form
would have been invalid.
"""
- FavoriteDrinkFormset = formset_factory(form=FavoriteDrinkForm, can_delete=True, can_order=True)
- formset = FavoriteDrinkFormset({
- 'form-0-name': '',
- 'form-0-DELETE': 'on', # no name!
- 'form-TOTAL_FORMS': 1,
- 'form-INITIAL_FORMS': 1,
- 'form-MIN_NUM_FORMS': 0,
- 'form-MAX_NUM_FORMS': 1
- })
+ FavoriteDrinkFormset = formset_factory(
+ form=FavoriteDrinkForm, can_delete=True, can_order=True
+ )
+ formset = FavoriteDrinkFormset(
+ {
+ "form-0-name": "",
+ "form-0-DELETE": "on", # no name!
+ "form-TOTAL_FORMS": 1,
+ "form-INITIAL_FORMS": 1,
+ "form-MIN_NUM_FORMS": 0,
+ "form-MAX_NUM_FORMS": 1,
+ }
+ )
self.assertTrue(formset.is_valid())
self.assertEqual(formset.ordered_forms, [])
@@ -808,22 +885,22 @@ class FormsFormsetTestCase(SimpleTestCase):
"""
# 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-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',
+ "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",
}
- formset = FavoriteDrinksFormSet(data, prefix='drinks')
+ formset = FavoriteDrinksFormSet(data, prefix="drinks")
self.assertFalse(formset.is_valid())
# Any errors raised by formset.clean() are available via the
# formset.non_form_errors() method.
for error in formset.non_form_errors():
- self.assertEqual(str(error), 'You may only specify a drink once.')
+ self.assertEqual(str(error), "You may only specify a drink once.")
# The valid case still works.
- data['drinks-1-name'] = 'Bloody Mary'
- formset = FavoriteDrinksFormSet(data, prefix='drinks')
+ data["drinks-1-name"] = "Bloody Mary"
+ formset = FavoriteDrinksFormSet(data, prefix="drinks")
self.assertTrue(formset.is_valid())
self.assertEqual(formset.non_form_errors(), [])
@@ -834,38 +911,44 @@ class FormsFormsetTestCase(SimpleTestCase):
LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=3)
formset = LimitedFavoriteDrinkFormSet()
self.assertHTMLEqual(
- '\n'.join(str(form) for form in formset.forms),
+ "\n".join(str(form) for form in formset.forms),
"""<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>"""
+<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)
+ LimitedFavoriteDrinkFormSet = formset_factory(
+ FavoriteDrinkForm, extra=3, max_num=0
+ )
formset = LimitedFavoriteDrinkFormSet()
self.assertEqual(formset.forms, [])
def test_limited_max_forms_two(self):
- LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=5, max_num=2)
+ LimitedFavoriteDrinkFormSet = formset_factory(
+ FavoriteDrinkForm, extra=5, max_num=2
+ )
formset = LimitedFavoriteDrinkFormSet()
self.assertHTMLEqual(
- '\n'.join(str(form) for form in formset.forms),
+ "\n".join(str(form) for form in formset.forms),
"""<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>"""
+<td><input type="text" name="form-1-name" id="id_form-1-name"></td></tr>""",
)
def test_limiting_extra_lest_than_max_num(self):
"""max_num has no effect when extra is less than max_num."""
- LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=1, max_num=2)
+ LimitedFavoriteDrinkFormSet = formset_factory(
+ FavoriteDrinkForm, extra=1, max_num=2
+ )
formset = LimitedFavoriteDrinkFormSet()
self.assertHTMLEqual(
- '\n'.join(str(form) for form in formset.forms),
+ "\n".join(str(form) for form in formset.forms),
"""<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>"""
+<td><input type="text" name="form-0-name" id="id_form-0-name"></td></tr>""",
)
def test_max_num_with_initial_data(self):
@@ -873,13 +956,13 @@ class FormsFormsetTestCase(SimpleTestCase):
# number of forms only controlled by the value of the initial and extra
# parameters.
LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=1)
- formset = LimitedFavoriteDrinkFormSet(initial=[{'name': 'Fernet and Coke'}])
+ formset = LimitedFavoriteDrinkFormSet(initial=[{"name": "Fernet and Coke"}])
self.assertHTMLEqual(
- '\n'.join(str(form) for form in formset.forms),
+ "\n".join(str(form) for form in formset.forms),
"""<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>"""
+<td><input type="text" name="form-1-name" id="id_form-1-name"></td></tr>""",
)
def test_max_num_zero(self):
@@ -887,24 +970,28 @@ class FormsFormsetTestCase(SimpleTestCase):
If max_num is 0 then no form is rendered at all, regardless of extra,
unless initial data is present.
"""
- LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=1, max_num=0)
+ LimitedFavoriteDrinkFormSet = formset_factory(
+ FavoriteDrinkForm, extra=1, max_num=0
+ )
formset = LimitedFavoriteDrinkFormSet()
self.assertEqual(formset.forms, [])
def test_max_num_zero_with_initial(self):
# initial trumps max_num
initial = [
- {'name': 'Fernet and Coke'},
- {'name': 'Bloody Mary'},
+ {"name": "Fernet and Coke"},
+ {"name": "Bloody Mary"},
]
- LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=1, max_num=0)
+ LimitedFavoriteDrinkFormSet = formset_factory(
+ FavoriteDrinkForm, extra=1, max_num=0
+ )
formset = LimitedFavoriteDrinkFormSet(initial=initial)
self.assertHTMLEqual(
- '\n'.join(str(form) for form in formset.forms),
+ "\n".join(str(form) for form in formset.forms),
"""<tr><th><label for="id_form-0-name">Name:</label></th>
<td><input id="id_form-0-name" name="form-0-name" type="text" value="Fernet and Coke"></td></tr>
<tr><th><label for="id_form-1-name">Name:</label></th>
-<td><input id="id_form-1-name" name="form-1-name" type="text" value="Bloody Mary"></td></tr>"""
+<td><input id="id_form-1-name" name="form-1-name" type="text" value="Bloody Mary"></td></tr>""",
)
def test_more_initial_than_max_num(self):
@@ -913,42 +1000,44 @@ class FormsFormsetTestCase(SimpleTestCase):
displayed (but no extra forms).
"""
initial = [
- {'name': 'Gin Tonic'},
- {'name': 'Bloody Mary'},
- {'name': 'Jack and Coke'},
+ {"name": "Gin Tonic"},
+ {"name": "Bloody Mary"},
+ {"name": "Jack and Coke"},
]
- LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=1, max_num=2)
+ LimitedFavoriteDrinkFormSet = formset_factory(
+ FavoriteDrinkForm, extra=1, max_num=2
+ )
formset = LimitedFavoriteDrinkFormSet(initial=initial)
self.assertHTMLEqual(
- '\n'.join(str(form) for form in formset.forms),
+ "\n".join(str(form) for form in formset.forms),
"""<tr><th><label for="id_form-0-name">Name:</label></th>
<td><input id="id_form-0-name" name="form-0-name" type="text" value="Gin Tonic"></td></tr>
<tr><th><label for="id_form-1-name">Name:</label></th>
<td><input id="id_form-1-name" name="form-1-name" type="text" value="Bloody Mary"></td></tr>
<tr><th><label for="id_form-2-name">Name:</label></th>
-<td><input id="id_form-2-name" name="form-2-name" type="text" value="Jack and Coke"></td></tr>"""
+<td><input id="id_form-2-name" name="form-2-name" type="text" value="Jack and Coke"></td></tr>""",
)
def test_default_absolute_max(self):
# absolute_max defaults to 2 * DEFAULT_MAX_NUM if max_num is None.
data = {
- 'form-TOTAL_FORMS': 2001,
- 'form-INITIAL_FORMS': '0',
- 'form-MAX_NUM_FORMS': '0',
+ "form-TOTAL_FORMS": 2001,
+ "form-INITIAL_FORMS": "0",
+ "form-MAX_NUM_FORMS": "0",
}
formset = FavoriteDrinksFormSet(data=data)
self.assertIs(formset.is_valid(), False)
self.assertEqual(
formset.non_form_errors(),
- ['Please submit at most 1000 forms.'],
+ ["Please submit at most 1000 forms."],
)
self.assertEqual(formset.absolute_max, 2000)
def test_absolute_max(self):
data = {
- 'form-TOTAL_FORMS': '2001',
- 'form-INITIAL_FORMS': '0',
- 'form-MAX_NUM_FORMS': '0',
+ "form-TOTAL_FORMS": "2001",
+ "form-INITIAL_FORMS": "0",
+ "form-MAX_NUM_FORMS": "0",
}
AbsoluteMaxFavoriteDrinksFormSet = formset_factory(
FavoriteDrinkForm,
@@ -958,20 +1047,20 @@ class FormsFormsetTestCase(SimpleTestCase):
self.assertIs(formset.is_valid(), True)
self.assertEqual(len(formset.forms), 2001)
# absolute_max provides a hard limit.
- data['form-TOTAL_FORMS'] = '3001'
+ data["form-TOTAL_FORMS"] = "3001"
formset = AbsoluteMaxFavoriteDrinksFormSet(data=data)
self.assertIs(formset.is_valid(), False)
self.assertEqual(len(formset.forms), 3000)
self.assertEqual(
formset.non_form_errors(),
- ['Please submit at most 1000 forms.'],
+ ["Please submit at most 1000 forms."],
)
def test_absolute_max_with_max_num(self):
data = {
- 'form-TOTAL_FORMS': '1001',
- 'form-INITIAL_FORMS': '0',
- 'form-MAX_NUM_FORMS': '0',
+ "form-TOTAL_FORMS": "1001",
+ "form-INITIAL_FORMS": "0",
+ "form-MAX_NUM_FORMS": "0",
}
LimitedFavoriteDrinksFormSet = formset_factory(
FavoriteDrinkForm,
@@ -983,7 +1072,7 @@ class FormsFormsetTestCase(SimpleTestCase):
self.assertEqual(len(formset.forms), 1000)
self.assertEqual(
formset.non_form_errors(),
- ['Please submit at most 30 forms.'],
+ ["Please submit at most 30 forms."],
)
def test_absolute_max_invalid(self):
@@ -998,14 +1087,16 @@ class FormsFormsetTestCase(SimpleTestCase):
One form from initial and extra=3 with max_num=2 results in the one
initial form and one extra.
"""
- LimitedFavoriteDrinkFormSet = formset_factory(FavoriteDrinkForm, extra=3, max_num=2)
- formset = LimitedFavoriteDrinkFormSet(initial=[{'name': 'Gin Tonic'}])
+ LimitedFavoriteDrinkFormSet = formset_factory(
+ FavoriteDrinkForm, extra=3, max_num=2
+ )
+ formset = LimitedFavoriteDrinkFormSet(initial=[{"name": "Gin Tonic"}])
self.assertHTMLEqual(
- '\n'.join(str(form) for form in formset.forms),
+ "\n".join(str(form) for form in formset.forms),
"""<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>"""
+<td><input type="text" name="form-1-name" id="id_form-1-name"></td></tr>""",
)
def test_management_form_field_names(self):
@@ -1023,34 +1114,36 @@ class FormsFormsetTestCase(SimpleTestCase):
def test_management_form_prefix(self):
"""The management form has the correct prefix."""
formset = FavoriteDrinksFormSet()
- self.assertEqual(formset.management_form.prefix, 'form')
+ self.assertEqual(formset.management_form.prefix, "form")
data = {
- 'form-TOTAL_FORMS': '2',
- 'form-INITIAL_FORMS': '0',
- 'form-MIN_NUM_FORMS': '0',
- 'form-MAX_NUM_FORMS': '0',
+ "form-TOTAL_FORMS": "2",
+ "form-INITIAL_FORMS": "0",
+ "form-MIN_NUM_FORMS": "0",
+ "form-MAX_NUM_FORMS": "0",
}
formset = FavoriteDrinksFormSet(data=data)
- self.assertEqual(formset.management_form.prefix, 'form')
+ self.assertEqual(formset.management_form.prefix, "form")
formset = FavoriteDrinksFormSet(initial={})
- self.assertEqual(formset.management_form.prefix, 'form')
+ self.assertEqual(formset.management_form.prefix, "form")
def test_non_form_errors(self):
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',
+ "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",
}
- formset = FavoriteDrinksFormSet(data, prefix='drinks')
+ formset = FavoriteDrinksFormSet(data, prefix="drinks")
self.assertFalse(formset.is_valid())
- self.assertEqual(formset.non_form_errors(), ['You may only specify a drink once.'])
+ self.assertEqual(
+ formset.non_form_errors(), ["You may only specify a drink once."]
+ )
self.assertEqual(
str(formset.non_form_errors()),
'<ul class="errorlist nonform"><li>'
- 'You may only specify a drink once.</li></ul>',
+ "You may only specify a drink once.</li></ul>",
)
def test_formset_iteration(self):
@@ -1093,21 +1186,23 @@ class FormsFormsetTestCase(SimpleTestCase):
"""
Formset works with SplitDateTimeField(initial=datetime.datetime.now).
"""
+
class SplitDateTimeForm(Form):
when = SplitDateTimeField(initial=datetime.datetime.now)
SplitDateTimeFormSet = formset_factory(SplitDateTimeForm)
data = {
- 'form-TOTAL_FORMS': '1',
- 'form-INITIAL_FORMS': '0',
- 'form-0-when_0': '1904-06-16',
- 'form-0-when_1': '15:51:33',
+ "form-TOTAL_FORMS": "1",
+ "form-INITIAL_FORMS": "0",
+ "form-0-when_0": "1904-06-16",
+ "form-0-when_1": "15:51:33",
}
formset = SplitDateTimeFormSet(data)
self.assertTrue(formset.is_valid())
def test_formset_error_class(self):
"""Formset's forms use the formset's error_class."""
+
class CustomErrorList(ErrorList):
pass
@@ -1116,6 +1211,7 @@ class FormsFormsetTestCase(SimpleTestCase):
def test_formset_calls_forms_is_valid(self):
"""Formsets call is_valid() on each form."""
+
class AnotherChoice(Choice):
def is_valid(self):
self.is_valid_called = True
@@ -1123,14 +1219,14 @@ class FormsFormsetTestCase(SimpleTestCase):
AnotherChoiceFormSet = formset_factory(AnotherChoice)
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',
+ "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",
}
- formset = AnotherChoiceFormSet(data, auto_id=False, prefix='choices')
+ formset = AnotherChoiceFormSet(data, auto_id=False, prefix="choices")
self.assertTrue(formset.is_valid())
self.assertTrue(all(form.is_valid_called for form in formset.forms))
@@ -1144,20 +1240,20 @@ class FormsFormsetTestCase(SimpleTestCase):
# someone fiddles with the mgmt form data...
formset = ChoiceFormSet(
{
- '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',
- 'choices-1-choice': 'One',
- 'choices-1-votes': '1',
- 'choices-2-choice': 'Two',
- 'choices-2-votes': '2',
- 'choices-3-choice': 'Three',
- 'choices-3-votes': '3',
+ "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",
+ "choices-1-choice": "One",
+ "choices-1-votes": "1",
+ "choices-2-choice": "Two",
+ "choices-2-votes": "2",
+ "choices-3-choice": "Three",
+ "choices-3-votes": "3",
},
- prefix='choices',
+ prefix="choices",
)
# But we still only instantiate 3 forms
self.assertEqual(len(formset.forms), 3)
@@ -1176,20 +1272,20 @@ class FormsFormsetTestCase(SimpleTestCase):
ChoiceFormSet = formset_factory(Choice, max_num=4)
formset = ChoiceFormSet(
{
- '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',
- 'choices-1-choice': 'One',
- 'choices-1-votes': '1',
- 'choices-2-choice': 'Two',
- 'choices-2-votes': '2',
- 'choices-3-choice': 'Three',
- 'choices-3-votes': '3',
+ "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",
+ "choices-1-choice": "One",
+ "choices-1-votes": "1",
+ "choices-2-choice": "Two",
+ "choices-2-votes": "2",
+ "choices-3-choice": "Three",
+ "choices-3-votes": "3",
},
- prefix='choices',
+ prefix="choices",
)
# Four forms are instantiated and no exception is raised
self.assertEqual(len(formset.forms), 4)
@@ -1201,44 +1297,47 @@ class FormsFormsetTestCase(SimpleTestCase):
If non_form_errors() is called without calling is_valid() first,
it should ensure that full_clean() is called.
"""
+
class BaseCustomFormSet(BaseFormSet):
def clean(self):
raise ValidationError("This is a non-form error")
ChoiceFormSet = formset_factory(Choice, formset=BaseCustomFormSet)
data = {
- 'choices-TOTAL_FORMS': '1',
- 'choices-INITIAL_FORMS': '0',
+ "choices-TOTAL_FORMS": "1",
+ "choices-INITIAL_FORMS": "0",
}
- formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
+ formset = ChoiceFormSet(data, auto_id=False, prefix="choices")
self.assertIsInstance(formset.non_form_errors(), ErrorList)
- self.assertEqual(list(formset.non_form_errors()), ['This is a non-form error'])
+ self.assertEqual(list(formset.non_form_errors()), ["This is a non-form error"])
def test_validate_max_ignores_forms_marked_for_deletion(self):
class CheckForm(Form):
field = IntegerField()
data = {
- 'check-TOTAL_FORMS': '2',
- 'check-INITIAL_FORMS': '0',
- 'check-MAX_NUM_FORMS': '1',
- 'check-0-field': '200',
- 'check-0-DELETE': '',
- 'check-1-field': '50',
- 'check-1-DELETE': 'on',
+ "check-TOTAL_FORMS": "2",
+ "check-INITIAL_FORMS": "0",
+ "check-MAX_NUM_FORMS": "1",
+ "check-0-field": "200",
+ "check-0-DELETE": "",
+ "check-1-field": "50",
+ "check-1-DELETE": "on",
}
- CheckFormSet = formset_factory(CheckForm, max_num=1, validate_max=True, can_delete=True)
- formset = CheckFormSet(data, prefix='check')
+ CheckFormSet = formset_factory(
+ CheckForm, max_num=1, validate_max=True, can_delete=True
+ )
+ formset = CheckFormSet(data, prefix="check")
self.assertTrue(formset.is_valid())
def test_formset_total_error_count(self):
"""A valid formset should have 0 total errors."""
data = [ # formset_data, expected error count
- ([('Calexico', '100')], 0),
- ([('Calexico', '')], 1),
- ([('', 'invalid')], 2),
- ([('Calexico', '100'), ('Calexico', '')], 1),
- ([('Calexico', ''), ('Calexico', '')], 2),
+ ([("Calexico", "100")], 0),
+ ([("Calexico", "")], 1),
+ ([("", "invalid")], 2),
+ ([("Calexico", "100"), ("Calexico", "")], 1),
+ ([("Calexico", ""), ("Calexico", "")], 2),
]
for formset_data, expected_error_count in data:
formset = self.make_choiceformset(formset_data)
@@ -1246,32 +1345,32 @@ class FormsFormsetTestCase(SimpleTestCase):
def test_formset_total_error_count_with_non_form_errors(self):
data = {
- 'choices-TOTAL_FORMS': '2', # the number of forms rendered
- 'choices-INITIAL_FORMS': '0', # the number of forms with initial data
- 'choices-MAX_NUM_FORMS': '2', # max number of forms - should be ignored
- 'choices-0-choice': 'Zero',
- 'choices-0-votes': '0',
- 'choices-1-choice': 'One',
- 'choices-1-votes': '1',
+ "choices-TOTAL_FORMS": "2", # the number of forms rendered
+ "choices-INITIAL_FORMS": "0", # the number of forms with initial data
+ "choices-MAX_NUM_FORMS": "2", # 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, max_num=1, validate_max=True)
- formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
+ formset = ChoiceFormSet(data, auto_id=False, prefix="choices")
self.assertEqual(formset.total_error_count(), 1)
- data['choices-1-votes'] = ''
- formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
+ data["choices-1-votes"] = ""
+ formset = ChoiceFormSet(data, auto_id=False, prefix="choices")
self.assertEqual(formset.total_error_count(), 2)
def test_html_safe(self):
formset = self.make_choiceformset()
- self.assertTrue(hasattr(formset, '__html__'))
+ self.assertTrue(hasattr(formset, "__html__"))
self.assertEqual(str(formset), formset.__html__())
def test_can_delete_extra_formset_forms(self):
ChoiceFormFormset = formset_factory(form=Choice, can_delete=True, extra=2)
formset = ChoiceFormFormset()
self.assertEqual(len(formset), 2)
- self.assertIn('DELETE', formset.forms[0].fields)
- self.assertIn('DELETE', formset.forms[1].fields)
+ self.assertIn("DELETE", formset.forms[0].fields)
+ self.assertIn("DELETE", formset.forms[1].fields)
def test_disable_delete_extra_formset_forms(self):
ChoiceFormFormset = formset_factory(
@@ -1282,31 +1381,37 @@ class FormsFormsetTestCase(SimpleTestCase):
)
formset = ChoiceFormFormset()
self.assertEqual(len(formset), 2)
- self.assertNotIn('DELETE', formset.forms[0].fields)
- self.assertNotIn('DELETE', formset.forms[1].fields)
+ self.assertNotIn("DELETE", formset.forms[0].fields)
+ self.assertNotIn("DELETE", formset.forms[1].fields)
- formset = ChoiceFormFormset(initial=[{'choice': 'Zero', 'votes': '1'}])
+ formset = ChoiceFormFormset(initial=[{"choice": "Zero", "votes": "1"}])
self.assertEqual(len(formset), 3)
- self.assertIn('DELETE', formset.forms[0].fields)
- self.assertNotIn('DELETE', formset.forms[1].fields)
- self.assertNotIn('DELETE', formset.forms[2].fields)
+ self.assertIn("DELETE", formset.forms[0].fields)
+ self.assertNotIn("DELETE", formset.forms[1].fields)
+ self.assertNotIn("DELETE", formset.forms[2].fields)
- formset = ChoiceFormFormset(data={
- 'form-0-choice': 'Zero',
- 'form-0-votes': '0',
- 'form-0-DELETE': 'on',
- 'form-1-choice': 'One',
- 'form-1-votes': '1',
- 'form-2-choice': '',
- 'form-2-votes': '',
- 'form-TOTAL_FORMS': '3',
- 'form-INITIAL_FORMS': '1',
- }, initial=[{'choice': 'Zero', 'votes': '1'}])
- self.assertEqual(formset.cleaned_data, [
- {'choice': 'Zero', 'votes': 0, 'DELETE': True},
- {'choice': 'One', 'votes': 1},
- {},
- ])
+ formset = ChoiceFormFormset(
+ data={
+ "form-0-choice": "Zero",
+ "form-0-votes": "0",
+ "form-0-DELETE": "on",
+ "form-1-choice": "One",
+ "form-1-votes": "1",
+ "form-2-choice": "",
+ "form-2-votes": "",
+ "form-TOTAL_FORMS": "3",
+ "form-INITIAL_FORMS": "1",
+ },
+ initial=[{"choice": "Zero", "votes": "1"}],
+ )
+ self.assertEqual(
+ formset.cleaned_data,
+ [
+ {"choice": "Zero", "votes": 0, "DELETE": True},
+ {"choice": "One", "votes": 1},
+ {},
+ ],
+ )
self.assertIs(formset._should_delete_form(formset.forms[0]), True)
self.assertIs(formset._should_delete_form(formset.forms[1]), False)
self.assertIs(formset._should_delete_form(formset.forms[2]), False)
@@ -1317,18 +1422,19 @@ class FormsFormsetTestCase(SimpleTestCase):
and ErrorList.
"""
from django.forms.renderers import Jinja2
+
renderer = Jinja2()
data = {
- 'choices-TOTAL_FORMS': '2',
- 'choices-INITIAL_FORMS': '0',
- 'choices-MIN_NUM_FORMS': '0',
- 'choices-0-choice': 'Zero',
- 'choices-0-votes': '',
- 'choices-1-choice': 'One',
- 'choices-1-votes': '',
+ "choices-TOTAL_FORMS": "2",
+ "choices-INITIAL_FORMS": "0",
+ "choices-MIN_NUM_FORMS": "0",
+ "choices-0-choice": "Zero",
+ "choices-0-votes": "",
+ "choices-1-choice": "One",
+ "choices-1-votes": "",
}
ChoiceFormSet = formset_factory(Choice, renderer=renderer)
- formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
+ formset = ChoiceFormSet(data, auto_id=False, prefix="choices")
self.assertEqual(formset.renderer, renderer)
self.assertEqual(formset.forms[0].renderer, renderer)
self.assertEqual(formset.management_form.renderer, renderer)
@@ -1336,16 +1442,16 @@ class FormsFormsetTestCase(SimpleTestCase):
self.assertEqual(formset.empty_form.renderer, renderer)
def test_repr(self):
- valid_formset = self.make_choiceformset([('test', 1)])
+ valid_formset = self.make_choiceformset([("test", 1)])
valid_formset.full_clean()
- invalid_formset = self.make_choiceformset([('test', '')])
+ invalid_formset = self.make_choiceformset([("test", "")])
invalid_formset.full_clean()
partially_invalid_formset = self.make_choiceformset(
- [('test', '1'), ('test', '')],
+ [("test", "1"), ("test", "")],
)
partially_invalid_formset.full_clean()
invalid_formset_non_form_errors_only = self.make_choiceformset(
- [('test', '')],
+ [("test", "")],
formset_class=ChoiceFormsetWithNonFormError,
)
invalid_formset_non_form_errors_only.full_clean()
@@ -1353,31 +1459,31 @@ class FormsFormsetTestCase(SimpleTestCase):
cases = [
(
self.make_choiceformset(),
- '<ChoiceFormSet: bound=False valid=Unknown total_forms=1>',
+ "<ChoiceFormSet: bound=False valid=Unknown total_forms=1>",
),
(
self.make_choiceformset(
formset_class=formset_factory(Choice, extra=10),
),
- '<ChoiceFormSet: bound=False valid=Unknown total_forms=10>',
+ "<ChoiceFormSet: bound=False valid=Unknown total_forms=10>",
),
(
self.make_choiceformset([]),
- '<ChoiceFormSet: bound=True valid=Unknown total_forms=0>',
+ "<ChoiceFormSet: bound=True valid=Unknown total_forms=0>",
),
(
- self.make_choiceformset([('test', 1)]),
- '<ChoiceFormSet: bound=True valid=Unknown total_forms=1>',
+ self.make_choiceformset([("test", 1)]),
+ "<ChoiceFormSet: bound=True valid=Unknown total_forms=1>",
),
- (valid_formset, '<ChoiceFormSet: bound=True valid=True total_forms=1>'),
- (invalid_formset, '<ChoiceFormSet: bound=True valid=False total_forms=1>'),
+ (valid_formset, "<ChoiceFormSet: bound=True valid=True total_forms=1>"),
+ (invalid_formset, "<ChoiceFormSet: bound=True valid=False total_forms=1>"),
(
partially_invalid_formset,
- '<ChoiceFormSet: bound=True valid=False total_forms=2>',
+ "<ChoiceFormSet: bound=True valid=False total_forms=2>",
),
(
invalid_formset_non_form_errors_only,
- '<ChoiceFormsetWithNonFormError: bound=True valid=False total_forms=1>',
+ "<ChoiceFormsetWithNonFormError: bound=True valid=False total_forms=1>",
),
]
for formset, expected_repr in cases:
@@ -1385,8 +1491,8 @@ class FormsFormsetTestCase(SimpleTestCase):
self.assertEqual(repr(formset), expected_repr)
def test_repr_do_not_trigger_validation(self):
- formset = self.make_choiceformset([('test', 1)])
- with mock.patch.object(formset, 'full_clean') as mocked_full_clean:
+ formset = self.make_choiceformset([("test", 1)])
+ with mock.patch.object(formset, "full_clean") as mocked_full_clean:
repr(formset)
mocked_full_clean.assert_not_called()
formset.is_valid()
@@ -1401,14 +1507,14 @@ class Jinja2FormsFormsetTestCase(FormsFormsetTestCase):
class FormsetAsTagTests(SimpleTestCase):
def setUp(self):
data = {
- 'choices-TOTAL_FORMS': '1',
- 'choices-INITIAL_FORMS': '0',
- 'choices-MIN_NUM_FORMS': '0',
- 'choices-MAX_NUM_FORMS': '0',
- 'choices-0-choice': 'Calexico',
- 'choices-0-votes': '100',
+ "choices-TOTAL_FORMS": "1",
+ "choices-INITIAL_FORMS": "0",
+ "choices-MIN_NUM_FORMS": "0",
+ "choices-MAX_NUM_FORMS": "0",
+ "choices-0-choice": "Calexico",
+ "choices-0-votes": "100",
}
- self.formset = ChoiceFormSet(data, auto_id=False, prefix='choices')
+ self.formset = ChoiceFormSet(data, auto_id=False, prefix="choices")
self.management_form_html = (
'<input type="hidden" name="choices-TOTAL_FORMS" value="1">'
'<input type="hidden" name="choices-INITIAL_FORMS" value="0">'
@@ -1419,30 +1525,33 @@ class FormsetAsTagTests(SimpleTestCase):
def test_as_table(self):
self.assertHTMLEqual(
self.formset.as_table(),
- self.management_form_html + (
- '<tr><th>Choice:</th><td>'
+ self.management_form_html
+ + (
+ "<tr><th>Choice:</th><td>"
'<input type="text" name="choices-0-choice" value="Calexico"></td></tr>'
- '<tr><th>Votes:</th><td>'
+ "<tr><th>Votes:</th><td>"
'<input type="number" name="choices-0-votes" value="100"></td></tr>'
- )
+ ),
)
def test_as_p(self):
self.assertHTMLEqual(
self.formset.as_p(),
- self.management_form_html + (
+ self.management_form_html
+ + (
'<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):
self.assertHTMLEqual(
self.formset.as_ul(),
- self.management_form_html + (
+ self.management_form_html
+ + (
'<li>Choice: <input type="text" name="choices-0-choice" value="Calexico"></li>'
'<li>Votes: <input type="number" name="choices-0-votes" value="100"></li>'
- )
+ ),
)
@@ -1466,9 +1575,9 @@ class TestIsBoundBehavior(SimpleTestCase):
self.assertEqual(
formset.non_form_errors(),
[
- 'ManagementForm data is missing or has been tampered with. '
- 'Missing fields: form-TOTAL_FORMS, form-INITIAL_FORMS. '
- 'You may need to file a bug report if the issue persists.',
+ "ManagementForm data is missing or has been tampered with. "
+ "Missing fields: form-TOTAL_FORMS, form-INITIAL_FORMS. "
+ "You may need to file a bug report if the issue persists.",
],
)
self.assertEqual(formset.errors, [])
@@ -1477,29 +1586,29 @@ class TestIsBoundBehavior(SimpleTestCase):
str(formset),
'<tr><td colspan="2">'
'<ul class="errorlist nonfield">'
- '<li>(Hidden field TOTAL_FORMS) This field is required.</li>'
- '<li>(Hidden field INITIAL_FORMS) This field is required.</li>'
- '</ul>'
+ "<li>(Hidden field TOTAL_FORMS) This field is required.</li>"
+ "<li>(Hidden field INITIAL_FORMS) This field is required.</li>"
+ "</ul>"
'<input type="hidden" name="form-TOTAL_FORMS" id="id_form-TOTAL_FORMS">'
'<input type="hidden" name="form-INITIAL_FORMS" id="id_form-INITIAL_FORMS">'
'<input type="hidden" name="form-MIN_NUM_FORMS" id="id_form-MIN_NUM_FORMS">'
'<input type="hidden" name="form-MAX_NUM_FORMS" id="id_form-MAX_NUM_FORMS">'
- '</td></tr>\n'
+ "</td></tr>\n",
)
def test_management_form_invalid_data(self):
data = {
- 'form-TOTAL_FORMS': 'two',
- 'form-INITIAL_FORMS': 'one',
+ "form-TOTAL_FORMS": "two",
+ "form-INITIAL_FORMS": "one",
}
formset = ArticleFormSet(data)
self.assertIs(formset.is_valid(), False)
self.assertEqual(
formset.non_form_errors(),
[
- 'ManagementForm data is missing or has been tampered with. '
- 'Missing fields: form-TOTAL_FORMS, form-INITIAL_FORMS. '
- 'You may need to file a bug report if the issue persists.',
+ "ManagementForm data is missing or has been tampered with. "
+ "Missing fields: form-TOTAL_FORMS, form-INITIAL_FORMS. "
+ "You may need to file a bug report if the issue persists.",
],
)
self.assertEqual(formset.errors, [])
@@ -1508,26 +1617,28 @@ class TestIsBoundBehavior(SimpleTestCase):
str(formset),
'<tr><td colspan="2">'
'<ul class="errorlist nonfield">'
- '<li>(Hidden field TOTAL_FORMS) Enter a whole number.</li>'
- '<li>(Hidden field INITIAL_FORMS) Enter a whole number.</li>'
- '</ul>'
+ "<li>(Hidden field TOTAL_FORMS) Enter a whole number.</li>"
+ "<li>(Hidden field INITIAL_FORMS) Enter a whole number.</li>"
+ "</ul>"
'<input type="hidden" name="form-TOTAL_FORMS" value="two" id="id_form-TOTAL_FORMS">'
'<input type="hidden" name="form-INITIAL_FORMS" value="one" id="id_form-INITIAL_FORMS">'
'<input type="hidden" name="form-MIN_NUM_FORMS" id="id_form-MIN_NUM_FORMS">'
'<input type="hidden" name="form-MAX_NUM_FORMS" id="id_form-MAX_NUM_FORMS">'
- '</td></tr>\n',
+ "</td></tr>\n",
)
def test_customize_management_form_error(self):
- formset = ArticleFormSet({}, error_messages={'missing_management_form': 'customized'})
+ formset = ArticleFormSet(
+ {}, error_messages={"missing_management_form": "customized"}
+ )
self.assertIs(formset.is_valid(), False)
- self.assertEqual(formset.non_form_errors(), ['customized'])
+ self.assertEqual(formset.non_form_errors(), ["customized"])
self.assertEqual(formset.errors, [])
def test_with_management_data_attrs_work_fine(self):
data = {
- 'form-TOTAL_FORMS': '1',
- 'form-INITIAL_FORMS': '0',
+ "form-TOTAL_FORMS": "1",
+ "form-INITIAL_FORMS": "0",
}
formset = ArticleFormSet(data)
self.assertEqual(0, formset.initial_form_count())
@@ -1540,30 +1651,29 @@ class TestIsBoundBehavior(SimpleTestCase):
def test_form_errors_are_caught_by_formset(self):
data = {
- 'form-TOTAL_FORMS': '2',
- 'form-INITIAL_FORMS': '0',
- 'form-0-title': 'Test',
- 'form-0-pub_date': '1904-06-16',
- 'form-1-title': 'Test',
- 'form-1-pub_date': '', # <-- this date is missing but required
+ "form-TOTAL_FORMS": "2",
+ "form-INITIAL_FORMS": "0",
+ "form-0-title": "Test",
+ "form-0-pub_date": "1904-06-16",
+ "form-1-title": "Test",
+ "form-1-pub_date": "", # <-- this date is missing but required
}
formset = ArticleFormSet(data)
self.assertFalse(formset.is_valid())
- self.assertEqual([{}, {'pub_date': ['This field is required.']}], formset.errors)
+ self.assertEqual(
+ [{}, {"pub_date": ["This field is required."]}], formset.errors
+ )
def test_empty_forms_are_unbound(self):
data = {
- 'form-TOTAL_FORMS': '1',
- 'form-INITIAL_FORMS': '0',
- 'form-0-title': 'Test',
- 'form-0-pub_date': '1904-06-16',
+ "form-TOTAL_FORMS": "1",
+ "form-INITIAL_FORMS": "0",
+ "form-0-title": "Test",
+ "form-0-pub_date": "1904-06-16",
}
unbound_formset = ArticleFormSet()
bound_formset = ArticleFormSet(data)
- empty_forms = [
- unbound_formset.empty_form,
- bound_formset.empty_form
- ]
+ empty_forms = [unbound_formset.empty_form, bound_formset.empty_form]
# Empty forms should be unbound
self.assertFalse(empty_forms[0].is_bound)
self.assertFalse(empty_forms[1].is_bound)
@@ -1579,17 +1689,24 @@ class TestIsBoundBehavior(TestIsBoundBehavior):
class TestEmptyFormSet(SimpleTestCase):
def test_empty_formset_is_valid(self):
"""An empty formset still calls clean()"""
+
class EmptyFsetWontValidate(BaseFormSet):
def clean(self):
- raise ValidationError('Clean method called')
+ raise ValidationError("Clean method called")
- EmptyFsetWontValidateFormset = formset_factory(FavoriteDrinkForm, extra=0, formset=EmptyFsetWontValidate)
+ EmptyFsetWontValidateFormset = formset_factory(
+ FavoriteDrinkForm, extra=0, formset=EmptyFsetWontValidate
+ )
formset = EmptyFsetWontValidateFormset(
- data={'form-INITIAL_FORMS': '0', 'form-TOTAL_FORMS': '0'},
+ data={"form-INITIAL_FORMS": "0", "form-TOTAL_FORMS": "0"},
prefix="form",
)
formset2 = EmptyFsetWontValidateFormset(
- data={'form-INITIAL_FORMS': '0', 'form-TOTAL_FORMS': '1', 'form-0-name': 'bah'},
+ data={
+ "form-INITIAL_FORMS": "0",
+ "form-TOTAL_FORMS": "1",
+ "form-0-name": "bah",
+ },
prefix="form",
)
self.assertFalse(formset.is_valid())
@@ -1597,33 +1714,36 @@ class TestEmptyFormSet(SimpleTestCase):
def test_empty_formset_media(self):
"""Media is available on empty formset."""
+
class MediaForm(Form):
class Media:
- js = ('some-file.js',)
- self.assertIn('some-file.js', str(formset_factory(MediaForm, extra=0)().media))
+ js = ("some-file.js",)
+
+ self.assertIn("some-file.js", str(formset_factory(MediaForm, extra=0)().media))
def test_empty_formset_is_multipart(self):
"""is_multipart() works with an empty formset."""
+
class FileForm(Form):
file = FileField()
+
self.assertTrue(formset_factory(FileForm, extra=0)().is_multipart())
class AllValidTests(SimpleTestCase):
-
def test_valid(self):
data = {
- 'choices-TOTAL_FORMS': '2',
- 'choices-INITIAL_FORMS': '0',
- 'choices-MIN_NUM_FORMS': '0',
- 'choices-0-choice': 'Zero',
- 'choices-0-votes': '0',
- 'choices-1-choice': 'One',
- 'choices-1-votes': '1',
+ "choices-TOTAL_FORMS": "2",
+ "choices-INITIAL_FORMS": "0",
+ "choices-MIN_NUM_FORMS": "0",
+ "choices-0-choice": "Zero",
+ "choices-0-votes": "0",
+ "choices-1-choice": "One",
+ "choices-1-votes": "1",
}
ChoiceFormSet = formset_factory(Choice)
- formset1 = ChoiceFormSet(data, auto_id=False, prefix='choices')
- formset2 = ChoiceFormSet(data, auto_id=False, prefix='choices')
+ formset1 = ChoiceFormSet(data, auto_id=False, prefix="choices")
+ formset2 = ChoiceFormSet(data, auto_id=False, prefix="choices")
self.assertIs(all_valid((formset1, formset2)), True)
expected_errors = [{}, {}]
self.assertEqual(formset1._errors, expected_errors)
@@ -1632,18 +1752,21 @@ class AllValidTests(SimpleTestCase):
def test_invalid(self):
"""all_valid() validates all forms, even when some are invalid."""
data = {
- 'choices-TOTAL_FORMS': '2',
- 'choices-INITIAL_FORMS': '0',
- 'choices-MIN_NUM_FORMS': '0',
- 'choices-0-choice': 'Zero',
- 'choices-0-votes': '',
- 'choices-1-choice': 'One',
- 'choices-1-votes': '',
+ "choices-TOTAL_FORMS": "2",
+ "choices-INITIAL_FORMS": "0",
+ "choices-MIN_NUM_FORMS": "0",
+ "choices-0-choice": "Zero",
+ "choices-0-votes": "",
+ "choices-1-choice": "One",
+ "choices-1-votes": "",
}
ChoiceFormSet = formset_factory(Choice)
- formset1 = ChoiceFormSet(data, auto_id=False, prefix='choices')
- formset2 = ChoiceFormSet(data, auto_id=False, prefix='choices')
+ formset1 = ChoiceFormSet(data, auto_id=False, prefix="choices")
+ formset2 = ChoiceFormSet(data, auto_id=False, prefix="choices")
self.assertIs(all_valid((formset1, formset2)), False)
- expected_errors = [{'votes': ['This field is required.']}, {'votes': ['This field is required.']}]
+ expected_errors = [
+ {"votes": ["This field is required."]},
+ {"votes": ["This field is required."]},
+ ]
self.assertEqual(formset1._errors, expected_errors)
self.assertEqual(formset2._errors, expected_errors)
diff --git a/tests/forms_tests/tests/test_i18n.py b/tests/forms_tests/tests/test_i18n.py
index 3590147933..777c84e4e4 100644
--- a/tests/forms_tests/tests/test_i18n.py
+++ b/tests/forms_tests/tests/test_i18n.py
@@ -1,5 +1,11 @@
from django.forms import (
- CharField, ChoiceField, Form, IntegerField, RadioSelect, Select, TextInput,
+ CharField,
+ ChoiceField,
+ Form,
+ IntegerField,
+ RadioSelect,
+ Select,
+ TextInput,
)
from django.test import SimpleTestCase
from django.utils import translation
@@ -11,96 +17,100 @@ from . import jinja2_tests
class FormsI18nTests(SimpleTestCase):
def test_lazy_labels(self):
class SomeForm(Form):
- username = CharField(max_length=10, label=gettext_lazy('username'))
+ username = CharField(max_length=10, label=gettext_lazy("username"))
f = SomeForm()
self.assertHTMLEqual(
f.as_p(),
'<p><label for="id_username">username:</label>'
- '<input id="id_username" type="text" name="username" maxlength="10" required></p>'
+ '<input id="id_username" type="text" name="username" maxlength="10" required></p>',
)
# Translations are done at rendering time, so multi-lingual apps can define forms)
- with translation.override('de'):
+ with translation.override("de"):
self.assertHTMLEqual(
f.as_p(),
'<p><label for="id_username">Benutzername:</label>'
- '<input id="id_username" type="text" name="username" maxlength="10" required></p>'
+ '<input id="id_username" type="text" name="username" maxlength="10" required></p>',
)
- with translation.override('pl'):
+ with translation.override("pl"):
self.assertHTMLEqual(
f.as_p(),
'<p><label for="id_username">nazwa u\u017cytkownika:</label>'
- '<input id="id_username" type="text" name="username" maxlength="10" required></p>'
+ '<input id="id_username" type="text" name="username" maxlength="10" required></p>',
)
def test_non_ascii_label(self):
class SomeForm(Form):
- field_1 = CharField(max_length=10, label=gettext_lazy('field_1'))
+ field_1 = CharField(max_length=10, label=gettext_lazy("field_1"))
field_2 = CharField(
max_length=10,
- label=gettext_lazy('field_2'),
- widget=TextInput(attrs={'id': 'field_2_id'}),
+ label=gettext_lazy("field_2"),
+ widget=TextInput(attrs={"id": "field_2_id"}),
)
f = SomeForm()
- self.assertHTMLEqual(f['field_1'].label_tag(), '<label for="id_field_1">field_1:</label>')
self.assertHTMLEqual(
- f['field_1'].legend_tag(),
+ f["field_1"].label_tag(), '<label for="id_field_1">field_1:</label>'
+ )
+ self.assertHTMLEqual(
+ f["field_1"].legend_tag(),
'<legend for="id_field_1">field_1:</legend>',
)
- self.assertHTMLEqual(f['field_2'].label_tag(), '<label for="field_2_id">field_2:</label>')
self.assertHTMLEqual(
- f['field_2'].legend_tag(),
+ f["field_2"].label_tag(), '<label for="field_2_id">field_2:</label>'
+ )
+ self.assertHTMLEqual(
+ f["field_2"].legend_tag(),
'<legend for="field_2_id">field_2:</legend>',
)
def test_non_ascii_choices(self):
class SomeForm(Form):
somechoice = ChoiceField(
- choices=(('\xc5', 'En tied\xe4'), ('\xf8', 'Mies'), ('\xdf', 'Nainen')),
+ choices=(("\xc5", "En tied\xe4"), ("\xf8", "Mies"), ("\xdf", "Nainen")),
widget=RadioSelect(),
- label='\xc5\xf8\xdf',
+ label="\xc5\xf8\xdf",
)
f = SomeForm()
self.assertHTMLEqual(
f.as_p(),
- '<p><label>\xc5\xf8\xdf:</label>'
+ "<p><label>\xc5\xf8\xdf:</label>"
'<div id="id_somechoice">\n'
'<div><label for="id_somechoice_0">'
'<input type="radio" id="id_somechoice_0" value="\xc5" name="somechoice" required> '
- 'En tied\xe4</label></div>\n'
+ "En tied\xe4</label></div>\n"
'<div><label for="id_somechoice_1">'
'<input type="radio" id="id_somechoice_1" value="\xf8" name="somechoice" required> '
'Mies</label></div>\n<div><label for="id_somechoice_2">'
'<input type="radio" id="id_somechoice_2" value="\xdf" name="somechoice" required> '
- 'Nainen</label></div>\n</div></p>'
+ "Nainen</label></div>\n</div></p>",
)
# Translated error messages
- with translation.override('ru'):
+ with translation.override("ru"):
f = SomeForm({})
self.assertHTMLEqual(
f.as_p(),
'<ul class="errorlist"><li>'
- '\u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c'
- '\u043d\u043e\u0435 \u043f\u043e\u043b\u0435.</li></ul>\n'
- '<p><label>\xc5\xf8\xdf:</label>'
+ "\u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c"
+ "\u043d\u043e\u0435 \u043f\u043e\u043b\u0435.</li></ul>\n"
+ "<p><label>\xc5\xf8\xdf:</label>"
' <div id="id_somechoice">\n<div><label for="id_somechoice_0">'
'<input type="radio" id="id_somechoice_0" value="\xc5" name="somechoice" required> '
- 'En tied\xe4</label></div>\n'
+ "En tied\xe4</label></div>\n"
'<div><label for="id_somechoice_1">'
'<input type="radio" id="id_somechoice_1" value="\xf8" name="somechoice" required> '
'Mies</label></div>\n<div><label for="id_somechoice_2">'
'<input type="radio" id="id_somechoice_2" value="\xdf" name="somechoice" required> '
- 'Nainen</label></div>\n</div></p>'
+ "Nainen</label></div>\n</div></p>",
)
def test_select_translated_text(self):
# Deep copying translated text shouldn't raise an error.
class CopyForm(Form):
- degree = IntegerField(widget=Select(choices=((1, gettext_lazy('test')),)))
+ degree = IntegerField(widget=Select(choices=((1, gettext_lazy("test")),)))
CopyForm()
diff --git a/tests/forms_tests/tests/test_input_formats.py b/tests/forms_tests/tests/test_input_formats.py
index 7b9da02a0c..3ac28b1b30 100644
--- a/tests/forms_tests/tests/test_input_formats.py
+++ b/tests/forms_tests/tests/test_input_formats.py
@@ -11,7 +11,7 @@ class LocalizedTimeTests(SimpleTestCase):
def setUp(self):
# nl/formats.py has customized TIME_INPUT_FORMATS:
# ['%H:%M:%S', '%H.%M:%S', '%H.%M', '%H:%M']
- activate('nl')
+ activate("nl")
def tearDown(self):
deactivate()
@@ -21,18 +21,18 @@ class LocalizedTimeTests(SimpleTestCase):
f = forms.TimeField()
# Parse a time in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('1:30:05 PM')
+ f.clean("1:30:05 PM")
# Parse a time in a valid format, get a parsed result
- result = f.clean('13:30:05')
+ result = f.clean("13:30:05")
self.assertEqual(result, time(13, 30, 5))
# The parsed result does a round trip
text = f.widget.format_value(result)
- self.assertEqual(text, '13:30:05')
+ self.assertEqual(text, "13:30:05")
# Parse a time in a valid, but non-default format, get a parsed result
- result = f.clean('13:30')
+ result = f.clean("13:30")
self.assertEqual(result, time(13, 30, 0))
# The parsed result does a round trip to default format
@@ -40,7 +40,7 @@ class LocalizedTimeTests(SimpleTestCase):
self.assertEqual(text, "13:30:00")
# ISO formats are accepted, even if not specified in formats.py
- result = f.clean('13:30:05.000155')
+ result = f.clean("13:30:05.000155")
self.assertEqual(result, time(13, 30, 5, 155))
def test_localized_timeField(self):
@@ -48,18 +48,18 @@ class LocalizedTimeTests(SimpleTestCase):
f = forms.TimeField(localize=True)
# Parse a time in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('1:30:05 PM')
+ f.clean("1:30:05 PM")
# Parse a time in a valid format, get a parsed result
- result = f.clean('13:30:05')
+ result = f.clean("13:30:05")
self.assertEqual(result, time(13, 30, 5))
# The parsed result does a round trip to the same format
text = f.widget.format_value(result)
- self.assertEqual(text, '13:30:05')
+ self.assertEqual(text, "13:30:05")
# Parse a time in a valid format, get a parsed result
- result = f.clean('13:30')
+ result = f.clean("13:30")
self.assertEqual(result, time(13, 30, 0))
# The parsed result does a round trip to default format
@@ -71,12 +71,12 @@ class LocalizedTimeTests(SimpleTestCase):
f = forms.TimeField(input_formats=["%H.%M.%S", "%H.%M"])
# Parse a time in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('1:30:05 PM')
+ f.clean("1:30:05 PM")
with self.assertRaises(ValidationError):
- f.clean('13:30:05')
+ f.clean("13:30:05")
# Parse a time in a valid format, get a parsed result
- result = f.clean('13.30.05')
+ result = f.clean("13.30.05")
self.assertEqual(result, time(13, 30, 5))
# The parsed result does a round trip to the same format
@@ -84,7 +84,7 @@ class LocalizedTimeTests(SimpleTestCase):
self.assertEqual(text, "13:30:05")
# Parse a time in a valid format, get a parsed result
- result = f.clean('13.30')
+ result = f.clean("13.30")
self.assertEqual(result, time(13, 30, 0))
# The parsed result does a round trip to default format
@@ -96,12 +96,12 @@ class LocalizedTimeTests(SimpleTestCase):
f = forms.TimeField(input_formats=["%H.%M.%S", "%H.%M"], localize=True)
# Parse a time in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('1:30:05 PM')
+ f.clean("1:30:05 PM")
with self.assertRaises(ValidationError):
- f.clean('13:30:05')
+ f.clean("13:30:05")
# Parse a time in a valid format, get a parsed result
- result = f.clean('13.30.05')
+ result = f.clean("13.30.05")
self.assertEqual(result, time(13, 30, 5))
# The parsed result does a round trip to the same format
@@ -109,7 +109,7 @@ class LocalizedTimeTests(SimpleTestCase):
self.assertEqual(text, "13:30:05")
# Parse a time in a valid format, get a parsed result
- result = f.clean('13.30')
+ result = f.clean("13.30")
self.assertEqual(result, time(13, 30, 0))
# The parsed result does a round trip to default format
@@ -125,18 +125,18 @@ class CustomTimeInputFormatsTests(SimpleTestCase):
f = forms.TimeField()
# Parse a time in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('13:30:05')
+ f.clean("13:30:05")
# Parse a time in a valid format, get a parsed result
- result = f.clean('1:30:05 PM')
+ result = f.clean("1:30:05 PM")
self.assertEqual(result, time(13, 30, 5))
# The parsed result does a round trip
text = f.widget.format_value(result)
- self.assertEqual(text, '01:30:05 PM')
+ self.assertEqual(text, "01:30:05 PM")
# Parse a time in a valid, but non-default format, get a parsed result
- result = f.clean('1:30 PM')
+ result = f.clean("1:30 PM")
self.assertEqual(result, time(13, 30, 0))
# The parsed result does a round trip to default format
@@ -148,18 +148,18 @@ class CustomTimeInputFormatsTests(SimpleTestCase):
f = forms.TimeField(localize=True)
# Parse a time in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('13:30:05')
+ f.clean("13:30:05")
# Parse a time in a valid format, get a parsed result
- result = f.clean('1:30:05 PM')
+ result = f.clean("1:30:05 PM")
self.assertEqual(result, time(13, 30, 5))
# The parsed result does a round trip to the same format
text = f.widget.format_value(result)
- self.assertEqual(text, '01:30:05 PM')
+ self.assertEqual(text, "01:30:05 PM")
# Parse a time in a valid format, get a parsed result
- result = f.clean('01:30 PM')
+ result = f.clean("01:30 PM")
self.assertEqual(result, time(13, 30, 0))
# The parsed result does a round trip to default format
@@ -171,12 +171,12 @@ class CustomTimeInputFormatsTests(SimpleTestCase):
f = forms.TimeField(input_formats=["%H.%M.%S", "%H.%M"])
# Parse a time in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('1:30:05 PM')
+ f.clean("1:30:05 PM")
with self.assertRaises(ValidationError):
- f.clean('13:30:05')
+ f.clean("13:30:05")
# Parse a time in a valid format, get a parsed result
- result = f.clean('13.30.05')
+ result = f.clean("13.30.05")
self.assertEqual(result, time(13, 30, 5))
# The parsed result does a round trip to the same format
@@ -184,7 +184,7 @@ class CustomTimeInputFormatsTests(SimpleTestCase):
self.assertEqual(text, "01:30:05 PM")
# Parse a time in a valid format, get a parsed result
- result = f.clean('13.30')
+ result = f.clean("13.30")
self.assertEqual(result, time(13, 30, 0))
# The parsed result does a round trip to default format
@@ -196,12 +196,12 @@ class CustomTimeInputFormatsTests(SimpleTestCase):
f = forms.TimeField(input_formats=["%H.%M.%S", "%H.%M"], localize=True)
# Parse a time in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('1:30:05 PM')
+ f.clean("1:30:05 PM")
with self.assertRaises(ValidationError):
- f.clean('13:30:05')
+ f.clean("13:30:05")
# Parse a time in a valid format, get a parsed result
- result = f.clean('13.30.05')
+ result = f.clean("13.30.05")
self.assertEqual(result, time(13, 30, 5))
# The parsed result does a round trip to the same format
@@ -209,7 +209,7 @@ class CustomTimeInputFormatsTests(SimpleTestCase):
self.assertEqual(text, "01:30:05 PM")
# Parse a time in a valid format, get a parsed result
- result = f.clean('13.30')
+ result = f.clean("13.30")
self.assertEqual(result, time(13, 30, 0))
# The parsed result does a round trip to default format
@@ -223,10 +223,10 @@ class SimpleTimeFormatTests(SimpleTestCase):
f = forms.TimeField()
# Parse a time in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('1:30:05 PM')
+ f.clean("1:30:05 PM")
# Parse a time in a valid format, get a parsed result
- result = f.clean('13:30:05')
+ result = f.clean("13:30:05")
self.assertEqual(result, time(13, 30, 5))
# The parsed result does a round trip to the same format
@@ -234,7 +234,7 @@ class SimpleTimeFormatTests(SimpleTestCase):
self.assertEqual(text, "13:30:05")
# Parse a time in a valid, but non-default format, get a parsed result
- result = f.clean('13:30')
+ result = f.clean("13:30")
self.assertEqual(result, time(13, 30, 0))
# The parsed result does a round trip to default format
@@ -246,10 +246,10 @@ class SimpleTimeFormatTests(SimpleTestCase):
f = forms.TimeField()
# Parse a time in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('1:30:05 PM')
+ f.clean("1:30:05 PM")
# Parse a time in a valid format, get a parsed result
- result = f.clean('13:30:05')
+ result = f.clean("13:30:05")
self.assertEqual(result, time(13, 30, 5))
# The parsed result does a round trip to the same format
@@ -257,7 +257,7 @@ class SimpleTimeFormatTests(SimpleTestCase):
self.assertEqual(text, "13:30:05")
# Parse a time in a valid format, get a parsed result
- result = f.clean('13:30')
+ result = f.clean("13:30")
self.assertEqual(result, time(13, 30, 0))
# The parsed result does a round trip to default format
@@ -269,10 +269,10 @@ class SimpleTimeFormatTests(SimpleTestCase):
f = forms.TimeField(input_formats=["%I:%M:%S %p", "%I:%M %p"])
# Parse a time in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('13:30:05')
+ f.clean("13:30:05")
# Parse a time in a valid format, get a parsed result
- result = f.clean('1:30:05 PM')
+ result = f.clean("1:30:05 PM")
self.assertEqual(result, time(13, 30, 5))
# The parsed result does a round trip to the same format
@@ -280,7 +280,7 @@ class SimpleTimeFormatTests(SimpleTestCase):
self.assertEqual(text, "13:30:05")
# Parse a time in a valid format, get a parsed result
- result = f.clean('1:30 PM')
+ result = f.clean("1:30 PM")
self.assertEqual(result, time(13, 30, 0))
# The parsed result does a round trip to default format
@@ -292,10 +292,10 @@ class SimpleTimeFormatTests(SimpleTestCase):
f = forms.TimeField(input_formats=["%I:%M:%S %p", "%I:%M %p"], localize=True)
# Parse a time in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('13:30:05')
+ f.clean("13:30:05")
# Parse a time in a valid format, get a parsed result
- result = f.clean('1:30:05 PM')
+ result = f.clean("1:30:05 PM")
self.assertEqual(result, time(13, 30, 5))
# The parsed result does a round trip to the same format
@@ -303,7 +303,7 @@ class SimpleTimeFormatTests(SimpleTestCase):
self.assertEqual(text, "13:30:05")
# Parse a time in a valid format, get a parsed result
- result = f.clean('1:30 PM')
+ result = f.clean("1:30 PM")
self.assertEqual(result, time(13, 30, 0))
# The parsed result does a round trip to default format
@@ -313,7 +313,7 @@ class SimpleTimeFormatTests(SimpleTestCase):
class LocalizedDateTests(SimpleTestCase):
def setUp(self):
- activate('de')
+ activate("de")
def tearDown(self):
deactivate()
@@ -323,21 +323,21 @@ class LocalizedDateTests(SimpleTestCase):
f = forms.DateField()
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('21/12/2010')
+ f.clean("21/12/2010")
# ISO formats are accepted, even if not specified in formats.py
- self.assertEqual(f.clean('2010-12-21'), date(2010, 12, 21))
+ self.assertEqual(f.clean("2010-12-21"), date(2010, 12, 21))
# Parse a date in a valid format, get a parsed result
- result = f.clean('21.12.2010')
+ result = f.clean("21.12.2010")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip
text = f.widget.format_value(result)
- self.assertEqual(text, '21.12.2010')
+ self.assertEqual(text, "21.12.2010")
# Parse a date in a valid, but non-default format, get a parsed result
- result = f.clean('21.12.10')
+ result = f.clean("21.12.10")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to default format
@@ -349,18 +349,18 @@ class LocalizedDateTests(SimpleTestCase):
f = forms.DateField(localize=True)
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('21/12/2010')
+ f.clean("21/12/2010")
# Parse a date in a valid format, get a parsed result
- result = f.clean('21.12.2010')
+ result = f.clean("21.12.2010")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to the same format
text = f.widget.format_value(result)
- self.assertEqual(text, '21.12.2010')
+ self.assertEqual(text, "21.12.2010")
# Parse a date in a valid format, get a parsed result
- result = f.clean('21.12.10')
+ result = f.clean("21.12.10")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to default format
@@ -372,14 +372,14 @@ class LocalizedDateTests(SimpleTestCase):
f = forms.DateField(input_formats=["%m.%d.%Y", "%m-%d-%Y"])
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('2010-12-21')
+ f.clean("2010-12-21")
with self.assertRaises(ValidationError):
- f.clean('21/12/2010')
+ f.clean("21/12/2010")
with self.assertRaises(ValidationError):
- f.clean('21.12.2010')
+ f.clean("21.12.2010")
# Parse a date in a valid format, get a parsed result
- result = f.clean('12.21.2010')
+ result = f.clean("12.21.2010")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to the same format
@@ -387,7 +387,7 @@ class LocalizedDateTests(SimpleTestCase):
self.assertEqual(text, "21.12.2010")
# Parse a date in a valid format, get a parsed result
- result = f.clean('12-21-2010')
+ result = f.clean("12-21-2010")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to default format
@@ -399,14 +399,14 @@ class LocalizedDateTests(SimpleTestCase):
f = forms.DateField(input_formats=["%m.%d.%Y", "%m-%d-%Y"], localize=True)
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('2010-12-21')
+ f.clean("2010-12-21")
with self.assertRaises(ValidationError):
- f.clean('21/12/2010')
+ f.clean("21/12/2010")
with self.assertRaises(ValidationError):
- f.clean('21.12.2010')
+ f.clean("21.12.2010")
# Parse a date in a valid format, get a parsed result
- result = f.clean('12.21.2010')
+ result = f.clean("12.21.2010")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to the same format
@@ -414,7 +414,7 @@ class LocalizedDateTests(SimpleTestCase):
self.assertEqual(text, "21.12.2010")
# Parse a date in a valid format, get a parsed result
- result = f.clean('12-21-2010')
+ result = f.clean("12-21-2010")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to default format
@@ -430,18 +430,18 @@ class CustomDateInputFormatsTests(SimpleTestCase):
f = forms.DateField()
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('2010-12-21')
+ f.clean("2010-12-21")
# Parse a date in a valid format, get a parsed result
- result = f.clean('21.12.2010')
+ result = f.clean("21.12.2010")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip
text = f.widget.format_value(result)
- self.assertEqual(text, '21.12.2010')
+ self.assertEqual(text, "21.12.2010")
# Parse a date in a valid, but non-default format, get a parsed result
- result = f.clean('21-12-2010')
+ result = f.clean("21-12-2010")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to default format
@@ -453,18 +453,18 @@ class CustomDateInputFormatsTests(SimpleTestCase):
f = forms.DateField(localize=True)
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('2010-12-21')
+ f.clean("2010-12-21")
# Parse a date in a valid format, get a parsed result
- result = f.clean('21.12.2010')
+ result = f.clean("21.12.2010")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to the same format
text = f.widget.format_value(result)
- self.assertEqual(text, '21.12.2010')
+ self.assertEqual(text, "21.12.2010")
# Parse a date in a valid format, get a parsed result
- result = f.clean('21-12-2010')
+ result = f.clean("21-12-2010")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to default format
@@ -476,12 +476,12 @@ class CustomDateInputFormatsTests(SimpleTestCase):
f = forms.DateField(input_formats=["%m.%d.%Y", "%m-%d-%Y"])
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('21.12.2010')
+ f.clean("21.12.2010")
with self.assertRaises(ValidationError):
- f.clean('2010-12-21')
+ f.clean("2010-12-21")
# Parse a date in a valid format, get a parsed result
- result = f.clean('12.21.2010')
+ result = f.clean("12.21.2010")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to the same format
@@ -489,7 +489,7 @@ class CustomDateInputFormatsTests(SimpleTestCase):
self.assertEqual(text, "21.12.2010")
# Parse a date in a valid format, get a parsed result
- result = f.clean('12-21-2010')
+ result = f.clean("12-21-2010")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to default format
@@ -501,12 +501,12 @@ class CustomDateInputFormatsTests(SimpleTestCase):
f = forms.DateField(input_formats=["%m.%d.%Y", "%m-%d-%Y"], localize=True)
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('21.12.2010')
+ f.clean("21.12.2010")
with self.assertRaises(ValidationError):
- f.clean('2010-12-21')
+ f.clean("2010-12-21")
# Parse a date in a valid format, get a parsed result
- result = f.clean('12.21.2010')
+ result = f.clean("12.21.2010")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to the same format
@@ -514,7 +514,7 @@ class CustomDateInputFormatsTests(SimpleTestCase):
self.assertEqual(text, "21.12.2010")
# Parse a date in a valid format, get a parsed result
- result = f.clean('12-21-2010')
+ result = f.clean("12-21-2010")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to default format
@@ -528,10 +528,10 @@ class SimpleDateFormatTests(SimpleTestCase):
f = forms.DateField()
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('21.12.2010')
+ f.clean("21.12.2010")
# Parse a date in a valid format, get a parsed result
- result = f.clean('2010-12-21')
+ result = f.clean("2010-12-21")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to the same format
@@ -539,7 +539,7 @@ class SimpleDateFormatTests(SimpleTestCase):
self.assertEqual(text, "2010-12-21")
# Parse a date in a valid, but non-default format, get a parsed result
- result = f.clean('12/21/2010')
+ result = f.clean("12/21/2010")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to default format
@@ -551,10 +551,10 @@ class SimpleDateFormatTests(SimpleTestCase):
f = forms.DateField()
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('21.12.2010')
+ f.clean("21.12.2010")
# Parse a date in a valid format, get a parsed result
- result = f.clean('2010-12-21')
+ result = f.clean("2010-12-21")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to the same format
@@ -562,7 +562,7 @@ class SimpleDateFormatTests(SimpleTestCase):
self.assertEqual(text, "2010-12-21")
# Parse a date in a valid format, get a parsed result
- result = f.clean('12/21/2010')
+ result = f.clean("12/21/2010")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to default format
@@ -574,10 +574,10 @@ class SimpleDateFormatTests(SimpleTestCase):
f = forms.DateField(input_formats=["%d.%m.%Y", "%d-%m-%Y"])
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('2010-12-21')
+ f.clean("2010-12-21")
# Parse a date in a valid format, get a parsed result
- result = f.clean('21.12.2010')
+ result = f.clean("21.12.2010")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to the same format
@@ -585,7 +585,7 @@ class SimpleDateFormatTests(SimpleTestCase):
self.assertEqual(text, "2010-12-21")
# Parse a date in a valid format, get a parsed result
- result = f.clean('21-12-2010')
+ result = f.clean("21-12-2010")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to default format
@@ -597,10 +597,10 @@ class SimpleDateFormatTests(SimpleTestCase):
f = forms.DateField(input_formats=["%d.%m.%Y", "%d-%m-%Y"], localize=True)
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('2010-12-21')
+ f.clean("2010-12-21")
# Parse a date in a valid format, get a parsed result
- result = f.clean('21.12.2010')
+ result = f.clean("21.12.2010")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to the same format
@@ -608,7 +608,7 @@ class SimpleDateFormatTests(SimpleTestCase):
self.assertEqual(text, "2010-12-21")
# Parse a date in a valid format, get a parsed result
- result = f.clean('21-12-2010')
+ result = f.clean("21-12-2010")
self.assertEqual(result, date(2010, 12, 21))
# The parsed result does a round trip to default format
@@ -618,7 +618,7 @@ class SimpleDateFormatTests(SimpleTestCase):
class LocalizedDateTimeTests(SimpleTestCase):
def setUp(self):
- activate('de')
+ activate("de")
def tearDown(self):
deactivate()
@@ -628,21 +628,23 @@ class LocalizedDateTimeTests(SimpleTestCase):
f = forms.DateTimeField()
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('1:30:05 PM 21/12/2010')
+ f.clean("1:30:05 PM 21/12/2010")
# ISO formats are accepted, even if not specified in formats.py
- self.assertEqual(f.clean('2010-12-21 13:30:05'), datetime(2010, 12, 21, 13, 30, 5))
+ self.assertEqual(
+ f.clean("2010-12-21 13:30:05"), datetime(2010, 12, 21, 13, 30, 5)
+ )
# Parse a date in a valid format, get a parsed result
- result = f.clean('21.12.2010 13:30:05')
+ result = f.clean("21.12.2010 13:30:05")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30, 5))
# The parsed result does a round trip
text = f.widget.format_value(result)
- self.assertEqual(text, '21.12.2010 13:30:05')
+ self.assertEqual(text, "21.12.2010 13:30:05")
# Parse a date in a valid, but non-default format, get a parsed result
- result = f.clean('21.12.2010 13:30')
+ result = f.clean("21.12.2010 13:30")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30))
# The parsed result does a round trip to default format
@@ -654,18 +656,18 @@ class LocalizedDateTimeTests(SimpleTestCase):
f = forms.DateTimeField(localize=True)
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('1:30:05 PM 21/12/2010')
+ f.clean("1:30:05 PM 21/12/2010")
# Parse a date in a valid format, get a parsed result
- result = f.clean('21.12.2010 13:30:05')
+ result = f.clean("21.12.2010 13:30:05")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30, 5))
# The parsed result does a round trip to the same format
text = f.widget.format_value(result)
- self.assertEqual(text, '21.12.2010 13:30:05')
+ self.assertEqual(text, "21.12.2010 13:30:05")
# Parse a date in a valid format, get a parsed result
- result = f.clean('21.12.2010 13:30')
+ result = f.clean("21.12.2010 13:30")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30))
# The parsed result does a round trip to default format
@@ -677,14 +679,14 @@ class LocalizedDateTimeTests(SimpleTestCase):
f = forms.DateTimeField(input_formats=["%H.%M.%S %m.%d.%Y", "%H.%M %m-%d-%Y"])
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('2010-12-21 13:30:05 13:30:05')
+ f.clean("2010-12-21 13:30:05 13:30:05")
with self.assertRaises(ValidationError):
- f.clean('1:30:05 PM 21/12/2010')
+ f.clean("1:30:05 PM 21/12/2010")
with self.assertRaises(ValidationError):
- f.clean('13:30:05 21.12.2010')
+ f.clean("13:30:05 21.12.2010")
# Parse a date in a valid format, get a parsed result
- result = f.clean('13.30.05 12.21.2010')
+ result = f.clean("13.30.05 12.21.2010")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30, 5))
# The parsed result does a round trip to the same format
@@ -692,7 +694,7 @@ class LocalizedDateTimeTests(SimpleTestCase):
self.assertEqual(text, "21.12.2010 13:30:05")
# Parse a date in a valid format, get a parsed result
- result = f.clean('13.30 12-21-2010')
+ result = f.clean("13.30 12-21-2010")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30))
# The parsed result does a round trip to default format
@@ -701,21 +703,23 @@ class LocalizedDateTimeTests(SimpleTestCase):
def test_localized_dateTimeField_with_inputformat(self):
"Localized DateTimeFields with manually specified input formats can accept those formats"
- f = forms.DateTimeField(input_formats=["%H.%M.%S %m.%d.%Y", "%H.%M %m-%d-%Y"], localize=True)
+ f = forms.DateTimeField(
+ input_formats=["%H.%M.%S %m.%d.%Y", "%H.%M %m-%d-%Y"], localize=True
+ )
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('2010/12/21 13:30:05')
+ f.clean("2010/12/21 13:30:05")
with self.assertRaises(ValidationError):
- f.clean('1:30:05 PM 21/12/2010')
+ f.clean("1:30:05 PM 21/12/2010")
with self.assertRaises(ValidationError):
- f.clean('13:30:05 21.12.2010')
+ f.clean("13:30:05 21.12.2010")
# Parse a date in a valid format, get a parsed result
- result = f.clean('13.30.05 12.21.2010')
+ result = f.clean("13.30.05 12.21.2010")
self.assertEqual(datetime(2010, 12, 21, 13, 30, 5), result)
# ISO format is always valid.
self.assertEqual(
- f.clean('2010-12-21 13:30:05'),
+ f.clean("2010-12-21 13:30:05"),
datetime(2010, 12, 21, 13, 30, 5),
)
# The parsed result does a round trip to the same format
@@ -723,7 +727,7 @@ class LocalizedDateTimeTests(SimpleTestCase):
self.assertEqual(text, "21.12.2010 13:30:05")
# Parse a date in a valid format, get a parsed result
- result = f.clean('13.30 12-21-2010')
+ result = f.clean("13.30 12-21-2010")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30))
# The parsed result does a round trip to default format
@@ -739,18 +743,18 @@ class CustomDateTimeInputFormatsTests(SimpleTestCase):
f = forms.DateTimeField()
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('2010/12/21 13:30:05')
+ f.clean("2010/12/21 13:30:05")
# Parse a date in a valid format, get a parsed result
- result = f.clean('1:30:05 PM 21/12/2010')
+ result = f.clean("1:30:05 PM 21/12/2010")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30, 5))
# The parsed result does a round trip
text = f.widget.format_value(result)
- self.assertEqual(text, '01:30:05 PM 21/12/2010')
+ self.assertEqual(text, "01:30:05 PM 21/12/2010")
# Parse a date in a valid, but non-default format, get a parsed result
- result = f.clean('1:30 PM 21-12-2010')
+ result = f.clean("1:30 PM 21-12-2010")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30))
# The parsed result does a round trip to default format
@@ -762,18 +766,18 @@ class CustomDateTimeInputFormatsTests(SimpleTestCase):
f = forms.DateTimeField(localize=True)
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('2010/12/21 13:30:05')
+ f.clean("2010/12/21 13:30:05")
# Parse a date in a valid format, get a parsed result
- result = f.clean('1:30:05 PM 21/12/2010')
+ result = f.clean("1:30:05 PM 21/12/2010")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30, 5))
# The parsed result does a round trip to the same format
text = f.widget.format_value(result)
- self.assertEqual(text, '01:30:05 PM 21/12/2010')
+ self.assertEqual(text, "01:30:05 PM 21/12/2010")
# Parse a date in a valid format, get a parsed result
- result = f.clean('1:30 PM 21-12-2010')
+ result = f.clean("1:30 PM 21-12-2010")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30))
# The parsed result does a round trip to default format
@@ -785,12 +789,12 @@ class CustomDateTimeInputFormatsTests(SimpleTestCase):
f = forms.DateTimeField(input_formats=["%m.%d.%Y %H:%M:%S", "%m-%d-%Y %H:%M"])
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('13:30:05 21.12.2010')
+ f.clean("13:30:05 21.12.2010")
with self.assertRaises(ValidationError):
- f.clean('2010/12/21 13:30:05')
+ f.clean("2010/12/21 13:30:05")
# Parse a date in a valid format, get a parsed result
- result = f.clean('12.21.2010 13:30:05')
+ result = f.clean("12.21.2010 13:30:05")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30, 5))
# The parsed result does a round trip to the same format
@@ -798,7 +802,7 @@ class CustomDateTimeInputFormatsTests(SimpleTestCase):
self.assertEqual(text, "01:30:05 PM 21/12/2010")
# Parse a date in a valid format, get a parsed result
- result = f.clean('12-21-2010 13:30')
+ result = f.clean("12-21-2010 13:30")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30))
# The parsed result does a round trip to default format
@@ -807,15 +811,17 @@ class CustomDateTimeInputFormatsTests(SimpleTestCase):
def test_localized_dateTimeField_with_inputformat(self):
"Localized DateTimeFields with manually specified input formats can accept those formats"
- f = forms.DateTimeField(input_formats=["%m.%d.%Y %H:%M:%S", "%m-%d-%Y %H:%M"], localize=True)
+ f = forms.DateTimeField(
+ input_formats=["%m.%d.%Y %H:%M:%S", "%m-%d-%Y %H:%M"], localize=True
+ )
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('13:30:05 21.12.2010')
+ f.clean("13:30:05 21.12.2010")
with self.assertRaises(ValidationError):
- f.clean('2010/12/21 13:30:05')
+ f.clean("2010/12/21 13:30:05")
# Parse a date in a valid format, get a parsed result
- result = f.clean('12.21.2010 13:30:05')
+ result = f.clean("12.21.2010 13:30:05")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30, 5))
# The parsed result does a round trip to the same format
@@ -823,7 +829,7 @@ class CustomDateTimeInputFormatsTests(SimpleTestCase):
self.assertEqual(text, "01:30:05 PM 21/12/2010")
# Parse a date in a valid format, get a parsed result
- result = f.clean('12-21-2010 13:30')
+ result = f.clean("12-21-2010 13:30")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30))
# The parsed result does a round trip to default format
@@ -837,10 +843,10 @@ class SimpleDateTimeFormatTests(SimpleTestCase):
f = forms.DateTimeField()
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('13:30:05 21.12.2010')
+ f.clean("13:30:05 21.12.2010")
# Parse a date in a valid format, get a parsed result
- result = f.clean('2010-12-21 13:30:05')
+ result = f.clean("2010-12-21 13:30:05")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30, 5))
# The parsed result does a round trip to the same format
@@ -848,7 +854,7 @@ class SimpleDateTimeFormatTests(SimpleTestCase):
self.assertEqual(text, "2010-12-21 13:30:05")
# Parse a date in a valid, but non-default format, get a parsed result
- result = f.clean('12/21/2010 13:30:05')
+ result = f.clean("12/21/2010 13:30:05")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30, 5))
# The parsed result does a round trip to default format
@@ -860,10 +866,10 @@ class SimpleDateTimeFormatTests(SimpleTestCase):
f = forms.DateTimeField()
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('13:30:05 21.12.2010')
+ f.clean("13:30:05 21.12.2010")
# Parse a date in a valid format, get a parsed result
- result = f.clean('2010-12-21 13:30:05')
+ result = f.clean("2010-12-21 13:30:05")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30, 5))
# The parsed result does a round trip to the same format
@@ -871,7 +877,7 @@ class SimpleDateTimeFormatTests(SimpleTestCase):
self.assertEqual(text, "2010-12-21 13:30:05")
# Parse a date in a valid format, get a parsed result
- result = f.clean('12/21/2010 13:30:05')
+ result = f.clean("12/21/2010 13:30:05")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30, 5))
# The parsed result does a round trip to default format
@@ -880,13 +886,15 @@ class SimpleDateTimeFormatTests(SimpleTestCase):
def test_dateTimeField_with_inputformat(self):
"DateTimeFields with manually specified input formats can accept those formats"
- f = forms.DateTimeField(input_formats=["%I:%M:%S %p %d.%m.%Y", "%I:%M %p %d-%m-%Y"])
+ f = forms.DateTimeField(
+ input_formats=["%I:%M:%S %p %d.%m.%Y", "%I:%M %p %d-%m-%Y"]
+ )
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('2010/12/21 13:30:05')
+ f.clean("2010/12/21 13:30:05")
# Parse a date in a valid format, get a parsed result
- result = f.clean('1:30:05 PM 21.12.2010')
+ result = f.clean("1:30:05 PM 21.12.2010")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30, 5))
# The parsed result does a round trip to the same format
@@ -894,7 +902,7 @@ class SimpleDateTimeFormatTests(SimpleTestCase):
self.assertEqual(text, "2010-12-21 13:30:05")
# Parse a date in a valid format, get a parsed result
- result = f.clean('1:30 PM 21-12-2010')
+ result = f.clean("1:30 PM 21-12-2010")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30))
# The parsed result does a round trip to default format
@@ -903,13 +911,15 @@ class SimpleDateTimeFormatTests(SimpleTestCase):
def test_localized_dateTimeField_with_inputformat(self):
"Localized DateTimeFields with manually specified input formats can accept those formats"
- f = forms.DateTimeField(input_formats=["%I:%M:%S %p %d.%m.%Y", "%I:%M %p %d-%m-%Y"], localize=True)
+ f = forms.DateTimeField(
+ input_formats=["%I:%M:%S %p %d.%m.%Y", "%I:%M %p %d-%m-%Y"], localize=True
+ )
# Parse a date in an unaccepted format; get an error
with self.assertRaises(ValidationError):
- f.clean('2010/12/21 13:30:05')
+ f.clean("2010/12/21 13:30:05")
# Parse a date in a valid format, get a parsed result
- result = f.clean('1:30:05 PM 21.12.2010')
+ result = f.clean("1:30:05 PM 21.12.2010")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30, 5))
# The parsed result does a round trip to the same format
@@ -917,7 +927,7 @@ class SimpleDateTimeFormatTests(SimpleTestCase):
self.assertEqual(text, "2010-12-21 13:30:05")
# Parse a date in a valid format, get a parsed result
- result = f.clean('1:30 PM 21-12-2010')
+ result = f.clean("1:30 PM 21-12-2010")
self.assertEqual(result, datetime(2010, 12, 21, 13, 30))
# The parsed result does a round trip to default format
diff --git a/tests/forms_tests/tests/test_media.py b/tests/forms_tests/tests/test_media.py
index d145560d9b..59fd74f4c9 100644
--- a/tests/forms_tests/tests/test_media.py
+++ b/tests/forms_tests/tests/test_media.py
@@ -4,7 +4,7 @@ from django.test import SimpleTestCase, override_settings
@override_settings(
- STATIC_URL='http://media.example.com/static/',
+ STATIC_URL="http://media.example.com/static/",
)
class FormsMediaTestCase(SimpleTestCase):
"""Tests for the media handling on widgets and forms"""
@@ -12,8 +12,12 @@ class FormsMediaTestCase(SimpleTestCase):
def test_construction(self):
# Check construction of media objects
m = Media(
- css={'all': ('path/to/css1', '/path/to/css2')},
- js=('/path/to/js1', 'http://media.other.com/path/to/js2', 'https://secure.other.com/path/to/js3'),
+ css={"all": ("path/to/css1", "/path/to/css2")},
+ js=(
+ "/path/to/js1",
+ "http://media.other.com/path/to/js2",
+ "https://secure.other.com/path/to/js3",
+ ),
)
self.assertEqual(
str(m),
@@ -21,19 +25,21 @@ class FormsMediaTestCase(SimpleTestCase):
<link href="/path/to/css2" media="all" rel="stylesheet">
<script src="/path/to/js1"></script>
<script src="http://media.other.com/path/to/js2"></script>
-<script src="https://secure.other.com/path/to/js3"></script>"""
+<script src="https://secure.other.com/path/to/js3"></script>""",
)
self.assertEqual(
repr(m),
"Media(css={'all': ['path/to/css1', '/path/to/css2']}, "
- "js=['/path/to/js1', 'http://media.other.com/path/to/js2', 'https://secure.other.com/path/to/js3'])"
+ "js=['/path/to/js1', 'http://media.other.com/path/to/js2', 'https://secure.other.com/path/to/js3'])",
)
class Foo:
- css = {
- 'all': ('path/to/css1', '/path/to/css2')
- }
- js = ('/path/to/js1', 'http://media.other.com/path/to/js2', 'https://secure.other.com/path/to/js3')
+ css = {"all": ("path/to/css1", "/path/to/css2")}
+ js = (
+ "/path/to/js1",
+ "http://media.other.com/path/to/js2",
+ "https://secure.other.com/path/to/js3",
+ )
m3 = Media(Foo)
self.assertEqual(
@@ -42,7 +48,7 @@ class FormsMediaTestCase(SimpleTestCase):
<link href="/path/to/css2" media="all" rel="stylesheet">
<script src="/path/to/js1"></script>
<script src="http://media.other.com/path/to/js2"></script>
-<script src="https://secure.other.com/path/to/js3"></script>"""
+<script src="https://secure.other.com/path/to/js3"></script>""",
)
# A widget can exist without a media definition
@@ -50,7 +56,7 @@ class FormsMediaTestCase(SimpleTestCase):
pass
w = MyWidget()
- self.assertEqual(str(w.media), '')
+ self.assertEqual(str(w.media), "")
def test_media_dsl(self):
###############################################################
@@ -62,10 +68,12 @@ class FormsMediaTestCase(SimpleTestCase):
# with the value of settings.MEDIA_URL
class MyWidget1(TextInput):
class Media:
- css = {
- 'all': ('path/to/css1', '/path/to/css2')
- }
- js = ('/path/to/js1', 'http://media.other.com/path/to/js2', 'https://secure.other.com/path/to/js3')
+ css = {"all": ("path/to/css1", "/path/to/css2")}
+ js = (
+ "/path/to/js1",
+ "http://media.other.com/path/to/js2",
+ "https://secure.other.com/path/to/js3",
+ )
w1 = MyWidget1()
self.assertEqual(
@@ -74,21 +82,21 @@ class FormsMediaTestCase(SimpleTestCase):
<link href="/path/to/css2" media="all" rel="stylesheet">
<script src="/path/to/js1"></script>
<script src="http://media.other.com/path/to/js2"></script>
-<script src="https://secure.other.com/path/to/js3"></script>"""
+<script src="https://secure.other.com/path/to/js3"></script>""",
)
# Media objects can be interrogated by media type
self.assertEqual(
- str(w1.media['css']),
+ str(w1.media["css"]),
"""<link href="http://media.example.com/static/path/to/css1" media="all" rel="stylesheet">
-<link href="/path/to/css2" media="all" rel="stylesheet">"""
+<link href="/path/to/css2" media="all" rel="stylesheet">""",
)
self.assertEqual(
- str(w1.media['js']),
+ str(w1.media["js"]),
"""<script src="/path/to/js1"></script>
<script src="http://media.other.com/path/to/js2"></script>
-<script src="https://secure.other.com/path/to/js3"></script>"""
+<script src="https://secure.other.com/path/to/js3"></script>""",
)
def test_combine_media(self):
@@ -96,24 +104,22 @@ class FormsMediaTestCase(SimpleTestCase):
# once. Duplicated media definitions are ignored.
class MyWidget1(TextInput):
class Media:
- css = {
- 'all': ('path/to/css1', '/path/to/css2')
- }
- js = ('/path/to/js1', 'http://media.other.com/path/to/js2', 'https://secure.other.com/path/to/js3')
+ css = {"all": ("path/to/css1", "/path/to/css2")}
+ js = (
+ "/path/to/js1",
+ "http://media.other.com/path/to/js2",
+ "https://secure.other.com/path/to/js3",
+ )
class MyWidget2(TextInput):
class Media:
- css = {
- 'all': ('/path/to/css2', '/path/to/css3')
- }
- js = ('/path/to/js1', '/path/to/js4')
+ css = {"all": ("/path/to/css2", "/path/to/css3")}
+ js = ("/path/to/js1", "/path/to/js4")
class MyWidget3(TextInput):
class Media:
- css = {
- 'all': ('path/to/css1', '/path/to/css3')
- }
- js = ('/path/to/js1', '/path/to/js4')
+ css = {"all": ("path/to/css1", "/path/to/css3")}
+ js = ("/path/to/js1", "/path/to/js4")
w1 = MyWidget1()
w2 = MyWidget2()
@@ -126,7 +132,7 @@ class FormsMediaTestCase(SimpleTestCase):
<script src="/path/to/js1"></script>
<script src="http://media.other.com/path/to/js2"></script>
<script src="/path/to/js4"></script>
-<script src="https://secure.other.com/path/to/js3"></script>"""
+<script src="https://secure.other.com/path/to/js3"></script>""",
)
# media addition hasn't affected the original objects
@@ -136,7 +142,7 @@ class FormsMediaTestCase(SimpleTestCase):
<link href="/path/to/css2" media="all" rel="stylesheet">
<script src="/path/to/js1"></script>
<script src="http://media.other.com/path/to/js2"></script>
-<script src="https://secure.other.com/path/to/js3"></script>"""
+<script src="https://secure.other.com/path/to/js3"></script>""",
)
# Regression check for #12879: specifying the same CSS or JS file
@@ -144,23 +150,29 @@ class FormsMediaTestCase(SimpleTestCase):
# only being included once.
class MyWidget4(TextInput):
class Media:
- css = {'all': ('/path/to/css1', '/path/to/css1')}
- js = ('/path/to/js1', '/path/to/js1')
+ css = {"all": ("/path/to/css1", "/path/to/css1")}
+ js = ("/path/to/js1", "/path/to/js1")
w4 = MyWidget4()
- self.assertEqual(str(w4.media), """<link href="/path/to/css1" media="all" rel="stylesheet">
-<script src="/path/to/js1"></script>""")
+ self.assertEqual(
+ str(w4.media),
+ """<link href="/path/to/css1" media="all" rel="stylesheet">
+<script src="/path/to/js1"></script>""",
+ )
def test_media_deduplication(self):
# A deduplication test applied directly to a Media object, to confirm
# that the deduplication doesn't only happen at the point of merging
# two or more media objects.
media = Media(
- css={'all': ('/path/to/css1', '/path/to/css1')},
- js=('/path/to/js1', '/path/to/js1'),
+ css={"all": ("/path/to/css1", "/path/to/css1")},
+ js=("/path/to/js1", "/path/to/js1"),
+ )
+ self.assertEqual(
+ str(media),
+ """<link href="/path/to/css1" media="all" rel="stylesheet">
+<script src="/path/to/js1"></script>""",
)
- self.assertEqual(str(media), """<link href="/path/to/css1" media="all" rel="stylesheet">
-<script src="/path/to/js1"></script>""")
def test_media_property(self):
###############################################################
@@ -170,38 +182,53 @@ class FormsMediaTestCase(SimpleTestCase):
# Widget media can be defined as a property
class MyWidget4(TextInput):
def _media(self):
- return Media(css={'all': ('/some/path',)}, js=('/some/js',))
+ return Media(css={"all": ("/some/path",)}, js=("/some/js",))
+
media = property(_media)
w4 = MyWidget4()
- self.assertEqual(str(w4.media), """<link href="/some/path" media="all" rel="stylesheet">
-<script src="/some/js"></script>""")
+ self.assertEqual(
+ str(w4.media),
+ """<link href="/some/path" media="all" rel="stylesheet">
+<script src="/some/js"></script>""",
+ )
# Media properties can reference the media of their parents
class MyWidget5(MyWidget4):
def _media(self):
- return super().media + Media(css={'all': ('/other/path',)}, js=('/other/js',))
+ return super().media + Media(
+ css={"all": ("/other/path",)}, js=("/other/js",)
+ )
+
media = property(_media)
w5 = MyWidget5()
- self.assertEqual(str(w5.media), """<link href="/some/path" media="all" rel="stylesheet">
+ self.assertEqual(
+ str(w5.media),
+ """<link href="/some/path" media="all" rel="stylesheet">
<link href="/other/path" media="all" rel="stylesheet">
<script src="/some/js"></script>
-<script src="/other/js"></script>""")
+<script src="/other/js"></script>""",
+ )
def test_media_property_parent_references(self):
# Media properties can reference the media of their parents,
# even if the parent media was defined using a class
class MyWidget1(TextInput):
class Media:
- css = {
- 'all': ('path/to/css1', '/path/to/css2')
- }
- js = ('/path/to/js1', 'http://media.other.com/path/to/js2', 'https://secure.other.com/path/to/js3')
+ css = {"all": ("path/to/css1", "/path/to/css2")}
+ js = (
+ "/path/to/js1",
+ "http://media.other.com/path/to/js2",
+ "https://secure.other.com/path/to/js3",
+ )
class MyWidget6(MyWidget1):
def _media(self):
- return super().media + Media(css={'all': ('/other/path',)}, js=('/other/js',))
+ return super().media + Media(
+ css={"all": ("/other/path",)}, js=("/other/js",)
+ )
+
media = property(_media)
w6 = MyWidget6()
@@ -213,7 +240,7 @@ class FormsMediaTestCase(SimpleTestCase):
<script src="/path/to/js1"></script>
<script src="/other/js"></script>
<script src="http://media.other.com/path/to/js2"></script>
-<script src="https://secure.other.com/path/to/js3"></script>"""
+<script src="https://secure.other.com/path/to/js3"></script>""",
)
def test_media_inheritance(self):
@@ -224,10 +251,12 @@ class FormsMediaTestCase(SimpleTestCase):
# If a widget extends another but provides no media definition, it inherits the parent widget's media
class MyWidget1(TextInput):
class Media:
- css = {
- 'all': ('path/to/css1', '/path/to/css2')
- }
- js = ('/path/to/js1', 'http://media.other.com/path/to/js2', 'https://secure.other.com/path/to/js3')
+ css = {"all": ("path/to/css1", "/path/to/css2")}
+ js = (
+ "/path/to/js1",
+ "http://media.other.com/path/to/js2",
+ "https://secure.other.com/path/to/js3",
+ )
class MyWidget7(MyWidget1):
pass
@@ -239,16 +268,14 @@ class FormsMediaTestCase(SimpleTestCase):
<link href="/path/to/css2" media="all" rel="stylesheet">
<script src="/path/to/js1"></script>
<script src="http://media.other.com/path/to/js2"></script>
-<script src="https://secure.other.com/path/to/js3"></script>"""
+<script src="https://secure.other.com/path/to/js3"></script>""",
)
# If a widget extends another but defines media, it extends the parent widget's media by default
class MyWidget8(MyWidget1):
class Media:
- css = {
- 'all': ('/path/to/css3', 'path/to/css1')
- }
- js = ('/path/to/js1', '/path/to/js4')
+ css = {"all": ("/path/to/css3", "path/to/css1")}
+ js = ("/path/to/js1", "/path/to/js4")
w8 = MyWidget8()
self.assertEqual(
@@ -259,7 +286,7 @@ class FormsMediaTestCase(SimpleTestCase):
<script src="/path/to/js1"></script>
<script src="http://media.other.com/path/to/js2"></script>
<script src="/path/to/js4"></script>
-<script src="https://secure.other.com/path/to/js3"></script>"""
+<script src="https://secure.other.com/path/to/js3"></script>""",
)
def test_media_inheritance_from_property(self):
@@ -267,22 +294,23 @@ class FormsMediaTestCase(SimpleTestCase):
# even if the parent defined media using a property.
class MyWidget1(TextInput):
class Media:
- css = {
- 'all': ('path/to/css1', '/path/to/css2')
- }
- js = ('/path/to/js1', 'http://media.other.com/path/to/js2', 'https://secure.other.com/path/to/js3')
+ css = {"all": ("path/to/css1", "/path/to/css2")}
+ js = (
+ "/path/to/js1",
+ "http://media.other.com/path/to/js2",
+ "https://secure.other.com/path/to/js3",
+ )
class MyWidget4(TextInput):
def _media(self):
- return Media(css={'all': ('/some/path',)}, js=('/some/js',))
+ return Media(css={"all": ("/some/path",)}, js=("/some/js",))
+
media = property(_media)
class MyWidget9(MyWidget4):
class Media:
- css = {
- 'all': ('/other/path',)
- }
- js = ('/other/js',)
+ css = {"all": ("/other/path",)}
+ js = ("/other/js",)
w9 = MyWidget9()
self.assertEqual(
@@ -290,40 +318,41 @@ class FormsMediaTestCase(SimpleTestCase):
"""<link href="/some/path" media="all" rel="stylesheet">
<link href="/other/path" media="all" rel="stylesheet">
<script src="/some/js"></script>
-<script src="/other/js"></script>"""
+<script src="/other/js"></script>""",
)
# A widget can disable media inheritance by specifying 'extend=False'
class MyWidget10(MyWidget1):
class Media:
extend = False
- css = {
- 'all': ('/path/to/css3', 'path/to/css1')
- }
- js = ('/path/to/js1', '/path/to/js4')
+ css = {"all": ("/path/to/css3", "path/to/css1")}
+ js = ("/path/to/js1", "/path/to/js4")
w10 = MyWidget10()
- self.assertEqual(str(w10.media), """<link href="/path/to/css3" media="all" rel="stylesheet">
+ self.assertEqual(
+ str(w10.media),
+ """<link href="/path/to/css3" media="all" rel="stylesheet">
<link href="http://media.example.com/static/path/to/css1" media="all" rel="stylesheet">
<script src="/path/to/js1"></script>
-<script src="/path/to/js4"></script>""")
+<script src="/path/to/js4"></script>""",
+ )
def test_media_inheritance_extends(self):
# A widget can explicitly enable full media inheritance by specifying 'extend=True'
class MyWidget1(TextInput):
class Media:
- css = {
- 'all': ('path/to/css1', '/path/to/css2')
- }
- js = ('/path/to/js1', 'http://media.other.com/path/to/js2', 'https://secure.other.com/path/to/js3')
+ css = {"all": ("path/to/css1", "/path/to/css2")}
+ js = (
+ "/path/to/js1",
+ "http://media.other.com/path/to/js2",
+ "https://secure.other.com/path/to/js3",
+ )
class MyWidget11(MyWidget1):
class Media:
extend = True
- css = {
- 'all': ('/path/to/css3', 'path/to/css1')
- }
- js = ('/path/to/js1', '/path/to/js4')
+ css = {"all": ("/path/to/css3", "path/to/css1")}
+ js = ("/path/to/js1", "/path/to/js4")
w11 = MyWidget11()
self.assertEqual(
@@ -334,25 +363,25 @@ class FormsMediaTestCase(SimpleTestCase):
<script src="/path/to/js1"></script>
<script src="http://media.other.com/path/to/js2"></script>
<script src="/path/to/js4"></script>
-<script src="https://secure.other.com/path/to/js3"></script>"""
+<script src="https://secure.other.com/path/to/js3"></script>""",
)
def test_media_inheritance_single_type(self):
# A widget can enable inheritance of one media type by specifying extend as a tuple
class MyWidget1(TextInput):
class Media:
- css = {
- 'all': ('path/to/css1', '/path/to/css2')
- }
- js = ('/path/to/js1', 'http://media.other.com/path/to/js2', 'https://secure.other.com/path/to/js3')
+ css = {"all": ("path/to/css1", "/path/to/css2")}
+ js = (
+ "/path/to/js1",
+ "http://media.other.com/path/to/js2",
+ "https://secure.other.com/path/to/js3",
+ )
class MyWidget12(MyWidget1):
class Media:
- extend = ('css',)
- css = {
- 'all': ('/path/to/css3', 'path/to/css1')
- }
- js = ('/path/to/js1', '/path/to/js4')
+ extend = ("css",)
+ css = {"all": ("/path/to/css3", "path/to/css1")}
+ js = ("/path/to/js1", "/path/to/js4")
w12 = MyWidget12()
self.assertEqual(
@@ -361,7 +390,7 @@ class FormsMediaTestCase(SimpleTestCase):
<link href="http://media.example.com/static/path/to/css1" media="all" rel="stylesheet">
<link href="/path/to/css2" media="all" rel="stylesheet">
<script src="/path/to/js1"></script>
-<script src="/path/to/js4"></script>"""
+<script src="/path/to/js4"></script>""",
)
def test_multi_media(self):
@@ -373,11 +402,11 @@ class FormsMediaTestCase(SimpleTestCase):
class MultimediaWidget(TextInput):
class Media:
css = {
- 'screen, print': ('/file1', '/file2'),
- 'screen': ('/file3',),
- 'print': ('/file4',)
+ "screen, print": ("/file1", "/file2"),
+ "screen": ("/file3",),
+ "print": ("/file4",),
}
- js = ('/path/to/js1', '/path/to/js4')
+ js = ("/path/to/js1", "/path/to/js4")
multimedia = MultimediaWidget()
self.assertEqual(
@@ -387,7 +416,7 @@ class FormsMediaTestCase(SimpleTestCase):
<link href="/file1" media="screen, print" rel="stylesheet">
<link href="/file2" media="screen, print" rel="stylesheet">
<script src="/path/to/js1"></script>
-<script src="/path/to/js4"></script>"""
+<script src="/path/to/js4"></script>""",
)
def test_multi_widget(self):
@@ -397,24 +426,22 @@ class FormsMediaTestCase(SimpleTestCase):
class MyWidget1(TextInput):
class Media:
- css = {
- 'all': ('path/to/css1', '/path/to/css2')
- }
- js = ('/path/to/js1', 'http://media.other.com/path/to/js2', 'https://secure.other.com/path/to/js3')
+ css = {"all": ("path/to/css1", "/path/to/css2")}
+ js = (
+ "/path/to/js1",
+ "http://media.other.com/path/to/js2",
+ "https://secure.other.com/path/to/js3",
+ )
class MyWidget2(TextInput):
class Media:
- css = {
- 'all': ('/path/to/css2', '/path/to/css3')
- }
- js = ('/path/to/js1', '/path/to/js4')
+ css = {"all": ("/path/to/css2", "/path/to/css3")}
+ js = ("/path/to/js1", "/path/to/js4")
class MyWidget3(TextInput):
class Media:
- css = {
- 'all': ('path/to/css1', '/path/to/css3')
- }
- js = ('/path/to/js1', '/path/to/js4')
+ css = {"all": ("path/to/css1", "/path/to/css3")}
+ js = ("/path/to/js1", "/path/to/js4")
# MultiWidgets have a default media definition that gets all the
# media from the component widgets
@@ -432,7 +459,7 @@ class FormsMediaTestCase(SimpleTestCase):
<script src="/path/to/js1"></script>
<script src="http://media.other.com/path/to/js2"></script>
<script src="/path/to/js4"></script>
-<script src="https://secure.other.com/path/to/js3"></script>"""
+<script src="https://secure.other.com/path/to/js3"></script>""",
)
def test_form_media(self):
@@ -442,29 +469,28 @@ class FormsMediaTestCase(SimpleTestCase):
class MyWidget1(TextInput):
class Media:
- css = {
- 'all': ('path/to/css1', '/path/to/css2')
- }
- js = ('/path/to/js1', 'http://media.other.com/path/to/js2', 'https://secure.other.com/path/to/js3')
+ css = {"all": ("path/to/css1", "/path/to/css2")}
+ js = (
+ "/path/to/js1",
+ "http://media.other.com/path/to/js2",
+ "https://secure.other.com/path/to/js3",
+ )
class MyWidget2(TextInput):
class Media:
- css = {
- 'all': ('/path/to/css2', '/path/to/css3')
- }
- js = ('/path/to/js1', '/path/to/js4')
+ css = {"all": ("/path/to/css2", "/path/to/css3")}
+ js = ("/path/to/js1", "/path/to/js4")
class MyWidget3(TextInput):
class Media:
- css = {
- 'all': ('path/to/css1', '/path/to/css3')
- }
- js = ('/path/to/js1', '/path/to/js4')
+ css = {"all": ("path/to/css1", "/path/to/css3")}
+ js = ("/path/to/js1", "/path/to/js4")
# You can ask a form for the media required by its widgets.
class MyForm(Form):
field1 = CharField(max_length=20, widget=MyWidget1())
field2 = CharField(max_length=20, widget=MyWidget2())
+
f1 = MyForm()
self.assertEqual(
str(f1.media),
@@ -474,12 +500,13 @@ class FormsMediaTestCase(SimpleTestCase):
<script src="/path/to/js1"></script>
<script src="http://media.other.com/path/to/js2"></script>
<script src="/path/to/js4"></script>
-<script src="https://secure.other.com/path/to/js3"></script>"""
+<script src="https://secure.other.com/path/to/js3"></script>""",
)
# Form media can be combined to produce a single media definition.
class AnotherForm(Form):
field3 = CharField(max_length=20, widget=MyWidget3())
+
f2 = AnotherForm()
self.assertEqual(
str(f1.media + f2.media),
@@ -489,7 +516,7 @@ class FormsMediaTestCase(SimpleTestCase):
<script src="/path/to/js1"></script>
<script src="http://media.other.com/path/to/js2"></script>
<script src="/path/to/js4"></script>
-<script src="https://secure.other.com/path/to/js3"></script>"""
+<script src="https://secure.other.com/path/to/js3"></script>""",
)
# Forms can also define media, following the same rules as widgets.
@@ -498,10 +525,9 @@ class FormsMediaTestCase(SimpleTestCase):
field2 = CharField(max_length=20, widget=MyWidget2())
class Media:
- js = ('/some/form/javascript',)
- css = {
- 'all': ('/some/form/css',)
- }
+ js = ("/some/form/javascript",)
+ css = {"all": ("/some/form/css",)}
+
f3 = FormWithMedia()
self.assertEqual(
str(f3.media),
@@ -513,12 +539,14 @@ class FormsMediaTestCase(SimpleTestCase):
<script src="/some/form/javascript"></script>
<script src="http://media.other.com/path/to/js2"></script>
<script src="/path/to/js4"></script>
-<script src="https://secure.other.com/path/to/js3"></script>"""
+<script src="https://secure.other.com/path/to/js3"></script>""",
)
# Media works in templates
self.assertEqual(
- Template("{{ form.media.js }}{{ form.media.css }}").render(Context({'form': f3})),
+ Template("{{ form.media.js }}{{ form.media.css }}").render(
+ Context({"form": f3})
+ ),
"""<script src="/path/to/js1"></script>
<script src="/some/form/javascript"></script>
<script src="http://media.other.com/path/to/js2"></script>
@@ -527,12 +555,12 @@ class FormsMediaTestCase(SimpleTestCase):
"""<link href="http://media.example.com/static/path/to/css1" media="all" rel="stylesheet">
<link href="/some/form/css" media="all" rel="stylesheet">
<link href="/path/to/css2" media="all" rel="stylesheet">
-<link href="/path/to/css3" media="all" rel="stylesheet">"""
+<link href="/path/to/css3" media="all" rel="stylesheet">""",
)
def test_html_safe(self):
- media = Media(css={'all': ['/path/to/css']}, js=['/path/to/js'])
- self.assertTrue(hasattr(Media, '__html__'))
+ media = Media(css={"all": ["/path/to/css"]}, js=["/path/to/js"])
+ self.assertTrue(hasattr(Media, "__html__"))
self.assertEqual(str(media), media.__html__())
def test_merge(self):
@@ -544,7 +572,10 @@ class FormsMediaTestCase(SimpleTestCase):
(([1, 2], [1, 3]), [1, 2, 3]),
(([1, 2], [3, 2]), [1, 3, 2]),
(([1, 2], [1, 2]), [1, 2]),
- ([[1, 2], [1, 3], [2, 3], [5, 7], [5, 6], [6, 7, 9], [8, 9]], [1, 5, 8, 2, 6, 3, 7, 9]),
+ (
+ [[1, 2], [1, 3], [2, 3], [5, 7], [5, 6], [6, 7, 9], [8, 9]],
+ [1, 5, 8, 2, 6, 3, 7, 9],
+ ),
((), []),
(([1, 2],), [1, 2]),
)
@@ -553,7 +584,7 @@ class FormsMediaTestCase(SimpleTestCase):
self.assertEqual(Media.merge(*lists), expected)
def test_merge_warning(self):
- msg = 'Detected duplicate Media files in an opposite order: [1, 2], [2, 1]'
+ msg = "Detected duplicate Media files in an opposite order: [1, 2], [2, 1]"
with self.assertWarnsMessage(RuntimeWarning, msg):
self.assertEqual(Media.merge([1, 2], [2, 1]), [1, 2])
@@ -561,51 +592,60 @@ class FormsMediaTestCase(SimpleTestCase):
"""
The relative order of scripts is preserved in a three-way merge.
"""
- widget1 = Media(js=['color-picker.js'])
- widget2 = Media(js=['text-editor.js'])
- widget3 = Media(js=['text-editor.js', 'text-editor-extras.js', 'color-picker.js'])
+ widget1 = Media(js=["color-picker.js"])
+ widget2 = Media(js=["text-editor.js"])
+ widget3 = Media(
+ js=["text-editor.js", "text-editor-extras.js", "color-picker.js"]
+ )
merged = widget1 + widget2 + widget3
- self.assertEqual(merged._js, ['text-editor.js', 'text-editor-extras.js', 'color-picker.js'])
+ self.assertEqual(
+ merged._js, ["text-editor.js", "text-editor-extras.js", "color-picker.js"]
+ )
def test_merge_js_three_way2(self):
# The merge prefers to place 'c' before 'b' and 'g' before 'h' to
# preserve the original order. The preference 'c'->'b' is overridden by
# widget3's media, but 'g'->'h' survives in the final ordering.
- widget1 = Media(js=['a', 'c', 'f', 'g', 'k'])
- widget2 = Media(js=['a', 'b', 'f', 'h', 'k'])
- widget3 = Media(js=['b', 'c', 'f', 'k'])
+ widget1 = Media(js=["a", "c", "f", "g", "k"])
+ widget2 = Media(js=["a", "b", "f", "h", "k"])
+ widget3 = Media(js=["b", "c", "f", "k"])
merged = widget1 + widget2 + widget3
- self.assertEqual(merged._js, ['a', 'b', 'c', 'f', 'g', 'h', 'k'])
+ self.assertEqual(merged._js, ["a", "b", "c", "f", "g", "h", "k"])
def test_merge_css_three_way(self):
- widget1 = Media(css={'screen': ['c.css'], 'all': ['d.css', 'e.css']})
- widget2 = Media(css={'screen': ['a.css']})
- widget3 = Media(css={'screen': ['a.css', 'b.css', 'c.css'], 'all': ['e.css']})
- widget4 = Media(css={'all': ['d.css', 'e.css'], 'screen': ['c.css']})
+ widget1 = Media(css={"screen": ["c.css"], "all": ["d.css", "e.css"]})
+ widget2 = Media(css={"screen": ["a.css"]})
+ widget3 = Media(css={"screen": ["a.css", "b.css", "c.css"], "all": ["e.css"]})
+ widget4 = Media(css={"all": ["d.css", "e.css"], "screen": ["c.css"]})
merged = widget1 + widget2
# c.css comes before a.css because widget1 + widget2 establishes this
# order.
- self.assertEqual(merged._css, {'screen': ['c.css', 'a.css'], 'all': ['d.css', 'e.css']})
+ self.assertEqual(
+ merged._css, {"screen": ["c.css", "a.css"], "all": ["d.css", "e.css"]}
+ )
merged = merged + widget3
# widget3 contains an explicit ordering of c.css and a.css.
- self.assertEqual(merged._css, {'screen': ['a.css', 'b.css', 'c.css'], 'all': ['d.css', 'e.css']})
+ self.assertEqual(
+ merged._css,
+ {"screen": ["a.css", "b.css", "c.css"], "all": ["d.css", "e.css"]},
+ )
# Media ordering does not matter.
merged = widget1 + widget4
- self.assertEqual(merged._css, {'screen': ['c.css'], 'all': ['d.css', 'e.css']})
+ self.assertEqual(merged._css, {"screen": ["c.css"], "all": ["d.css", "e.css"]})
def test_add_js_deduplication(self):
- widget1 = Media(js=['a', 'b', 'c'])
- widget2 = Media(js=['a', 'b'])
- widget3 = Media(js=['a', 'c', 'b'])
+ widget1 = Media(js=["a", "b", "c"])
+ widget2 = Media(js=["a", "b"])
+ widget3 = Media(js=["a", "c", "b"])
merged = widget1 + widget1
- self.assertEqual(merged._js_lists, [['a', 'b', 'c']])
- self.assertEqual(merged._js, ['a', 'b', 'c'])
+ self.assertEqual(merged._js_lists, [["a", "b", "c"]])
+ self.assertEqual(merged._js, ["a", "b", "c"])
merged = widget1 + widget2
- self.assertEqual(merged._js_lists, [['a', 'b', 'c'], ['a', 'b']])
- self.assertEqual(merged._js, ['a', 'b', 'c'])
+ self.assertEqual(merged._js_lists, [["a", "b", "c"], ["a", "b"]])
+ self.assertEqual(merged._js, ["a", "b", "c"])
# Lists with items in a different order are preserved when added.
merged = widget1 + widget3
- self.assertEqual(merged._js_lists, [['a', 'b', 'c'], ['a', 'c', 'b']])
+ self.assertEqual(merged._js_lists, [["a", "b", "c"], ["a", "c", "b"]])
msg = (
"Detected duplicate Media files in an opposite order: "
"['a', 'b', 'c'], ['a', 'c', 'b']"
@@ -614,25 +654,31 @@ class FormsMediaTestCase(SimpleTestCase):
merged._js
def test_add_css_deduplication(self):
- widget1 = Media(css={'screen': ['a.css'], 'all': ['b.css']})
- widget2 = Media(css={'screen': ['c.css']})
- widget3 = Media(css={'screen': ['a.css'], 'all': ['b.css', 'c.css']})
- widget4 = Media(css={'screen': ['a.css'], 'all': ['c.css', 'b.css']})
+ widget1 = Media(css={"screen": ["a.css"], "all": ["b.css"]})
+ widget2 = Media(css={"screen": ["c.css"]})
+ widget3 = Media(css={"screen": ["a.css"], "all": ["b.css", "c.css"]})
+ widget4 = Media(css={"screen": ["a.css"], "all": ["c.css", "b.css"]})
merged = widget1 + widget1
- self.assertEqual(merged._css_lists, [{'screen': ['a.css'], 'all': ['b.css']}])
- self.assertEqual(merged._css, {'screen': ['a.css'], 'all': ['b.css']})
+ self.assertEqual(merged._css_lists, [{"screen": ["a.css"], "all": ["b.css"]}])
+ self.assertEqual(merged._css, {"screen": ["a.css"], "all": ["b.css"]})
merged = widget1 + widget2
- self.assertEqual(merged._css_lists, [
- {'screen': ['a.css'], 'all': ['b.css']},
- {'screen': ['c.css']},
- ])
- self.assertEqual(merged._css, {'screen': ['a.css', 'c.css'], 'all': ['b.css']})
+ self.assertEqual(
+ merged._css_lists,
+ [
+ {"screen": ["a.css"], "all": ["b.css"]},
+ {"screen": ["c.css"]},
+ ],
+ )
+ self.assertEqual(merged._css, {"screen": ["a.css", "c.css"], "all": ["b.css"]})
merged = widget3 + widget4
# Ordering within lists is preserved.
- self.assertEqual(merged._css_lists, [
- {'screen': ['a.css'], 'all': ['b.css', 'c.css']},
- {'screen': ['a.css'], 'all': ['c.css', 'b.css']}
- ])
+ self.assertEqual(
+ merged._css_lists,
+ [
+ {"screen": ["a.css"], "all": ["b.css", "c.css"]},
+ {"screen": ["a.css"], "all": ["c.css", "b.css"]},
+ ],
+ )
msg = (
"Detected duplicate Media files in an opposite order: "
"['b.css', 'c.css'], ['c.css', 'b.css']"
@@ -641,8 +687,8 @@ class FormsMediaTestCase(SimpleTestCase):
merged._css
def test_add_empty(self):
- media = Media(css={'screen': ['a.css']}, js=['a'])
+ media = Media(css={"screen": ["a.css"]}, js=["a"])
empty_media = Media()
merged = media + empty_media
- self.assertEqual(merged._css_lists, [{'screen': ['a.css']}])
- self.assertEqual(merged._js_lists, [['a']])
+ self.assertEqual(merged._css_lists, [{"screen": ["a.css"]}])
+ self.assertEqual(merged._js_lists, [["a"]])
diff --git a/tests/forms_tests/tests/test_renderers.py b/tests/forms_tests/tests/test_renderers.py
index 47452fa489..3e973ad8fc 100644
--- a/tests/forms_tests/tests/test_renderers.py
+++ b/tests/forms_tests/tests/test_renderers.py
@@ -2,7 +2,10 @@ import os
import unittest
from django.forms.renderers import (
- BaseRenderer, DjangoTemplates, Jinja2, TemplatesSetting,
+ BaseRenderer,
+ DjangoTemplates,
+ Jinja2,
+ TemplatesSetting,
)
from django.test import SimpleTestCase
@@ -13,38 +16,39 @@ except ImportError:
class SharedTests:
- expected_widget_dir = 'templates'
+ expected_widget_dir = "templates"
def test_installed_apps_template_found(self):
"""Can find a custom template in INSTALLED_APPS."""
renderer = self.renderer()
# Found because forms_tests is .
- tpl = renderer.get_template('forms_tests/custom_widget.html')
+ tpl = renderer.get_template("forms_tests/custom_widget.html")
expected_path = os.path.abspath(
os.path.join(
os.path.dirname(__file__),
- '..',
- self.expected_widget_dir + '/forms_tests/custom_widget.html',
+ "..",
+ self.expected_widget_dir + "/forms_tests/custom_widget.html",
)
)
self.assertEqual(tpl.origin.name, expected_path)
class BaseTemplateRendererTests(SimpleTestCase):
-
def test_get_renderer(self):
- with self.assertRaisesMessage(NotImplementedError, 'subclasses must implement get_template()'):
- BaseRenderer().get_template('')
+ with self.assertRaisesMessage(
+ NotImplementedError, "subclasses must implement get_template()"
+ ):
+ BaseRenderer().get_template("")
class DjangoTemplatesTests(SharedTests, SimpleTestCase):
renderer = DjangoTemplates
-@unittest.skipIf(jinja2 is None, 'jinja2 required')
+@unittest.skipIf(jinja2 is None, "jinja2 required")
class Jinja2Tests(SharedTests, SimpleTestCase):
renderer = Jinja2
- expected_widget_dir = 'jinja2'
+ expected_widget_dir = "jinja2"
class TemplatesSettingTests(SharedTests, SimpleTestCase):
diff --git a/tests/forms_tests/tests/test_utils.py b/tests/forms_tests/tests/test_utils.py
index e0e9a0e22e..c4a2e5c651 100644
--- a/tests/forms_tests/tests/test_utils.py
+++ b/tests/forms_tests/tests/test_utils.py
@@ -16,28 +16,31 @@ class FormsUtilsTestCase(SimpleTestCase):
# flatatt #
###########
- self.assertEqual(flatatt({'id': "header"}), ' id="header"')
- self.assertEqual(flatatt({'class': "news", 'title': "Read this"}), ' class="news" title="Read this"')
+ self.assertEqual(flatatt({"id": "header"}), ' id="header"')
self.assertEqual(
- flatatt({'class': "news", 'title': "Read this", 'required': "required"}),
- ' class="news" required="required" title="Read this"'
+ flatatt({"class": "news", "title": "Read this"}),
+ ' class="news" title="Read this"',
)
self.assertEqual(
- flatatt({'class': "news", 'title': "Read this", 'required': True}),
- ' class="news" title="Read this" required'
+ flatatt({"class": "news", "title": "Read this", "required": "required"}),
+ ' class="news" required="required" title="Read this"',
)
self.assertEqual(
- flatatt({'class': "news", 'title': "Read this", 'required': False}),
- ' class="news" title="Read this"'
+ flatatt({"class": "news", "title": "Read this", "required": True}),
+ ' class="news" title="Read this" required',
)
- self.assertEqual(flatatt({'class': None}), '')
- self.assertEqual(flatatt({}), '')
+ self.assertEqual(
+ flatatt({"class": "news", "title": "Read this", "required": False}),
+ ' class="news" title="Read this"',
+ )
+ self.assertEqual(flatatt({"class": None}), "")
+ self.assertEqual(flatatt({}), "")
def test_flatatt_no_side_effects(self):
"""
flatatt() does not modify the dict passed in.
"""
- attrs = {'foo': 'bar', 'true': True, 'false': False}
+ attrs = {"foo": "bar", "true": True, "false": False}
attrs_copy = copy.copy(attrs)
self.assertEqual(attrs, attrs_copy)
@@ -58,46 +61,62 @@ class FormsUtilsTestCase(SimpleTestCase):
# Can take a string.
self.assertHTMLEqual(
str(ErrorList(ValidationError("There was an error.").messages)),
- '<ul class="errorlist"><li>There was an error.</li></ul>'
+ '<ul class="errorlist"><li>There was an error.</li></ul>',
)
# Can take a Unicode string.
self.assertHTMLEqual(
str(ErrorList(ValidationError("Not \u03C0.").messages)),
- '<ul class="errorlist"><li>Not π.</li></ul>'
+ '<ul class="errorlist"><li>Not π.</li></ul>',
)
# Can take a lazy string.
self.assertHTMLEqual(
str(ErrorList(ValidationError(gettext_lazy("Error.")).messages)),
- '<ul class="errorlist"><li>Error.</li></ul>'
+ '<ul class="errorlist"><li>Error.</li></ul>',
)
# Can take a list.
self.assertHTMLEqual(
str(ErrorList(ValidationError(["Error one.", "Error two."]).messages)),
- '<ul class="errorlist"><li>Error one.</li><li>Error two.</li></ul>'
+ '<ul class="errorlist"><li>Error one.</li><li>Error two.</li></ul>',
)
# Can take a dict.
self.assertHTMLEqual(
- str(ErrorList(sorted(ValidationError({'error_1': "1. Error one.", 'error_2': "2. Error two."}).messages))),
- '<ul class="errorlist"><li>1. Error one.</li><li>2. Error two.</li></ul>'
+ str(
+ ErrorList(
+ sorted(
+ ValidationError(
+ {"error_1": "1. Error one.", "error_2": "2. Error two."}
+ ).messages
+ )
+ )
+ ),
+ '<ul class="errorlist"><li>1. Error one.</li><li>2. Error two.</li></ul>',
)
# Can take a mixture in a list.
self.assertHTMLEqual(
- str(ErrorList(sorted(ValidationError([
- "1. First error.",
- "2. Not \u03C0.",
- gettext_lazy("3. Error."),
- {
- 'error_1': "4. First dict error.",
- 'error_2': "5. Second dict error.",
- },
- ]).messages))),
+ str(
+ ErrorList(
+ sorted(
+ ValidationError(
+ [
+ "1. First error.",
+ "2. Not \u03C0.",
+ gettext_lazy("3. Error."),
+ {
+ "error_1": "4. First dict error.",
+ "error_2": "5. Second dict error.",
+ },
+ ]
+ ).messages
+ )
+ )
+ ),
'<ul class="errorlist">'
- '<li>1. First error.</li>'
- '<li>2. Not π.</li>'
- '<li>3. Error.</li>'
- '<li>4. First dict error.</li>'
- '<li>5. Second dict error.</li>'
- '</ul>'
+ "<li>1. First error.</li>"
+ "<li>2. Not π.</li>"
+ "<li>3. Error.</li>"
+ "<li>4. First dict error.</li>"
+ "<li>5. Second dict error.</li>"
+ "</ul>",
)
class VeryBadError:
@@ -107,7 +126,7 @@ class FormsUtilsTestCase(SimpleTestCase):
# Can take a non-string.
self.assertHTMLEqual(
str(ErrorList(ValidationError(VeryBadError()).messages)),
- '<ul class="errorlist"><li>A very bad error.</li></ul>'
+ '<ul class="errorlist"><li>A very bad error.</li></ul>',
)
# Escapes non-safe input but not input marked safe.
@@ -115,36 +134,38 @@ class FormsUtilsTestCase(SimpleTestCase):
self.assertHTMLEqual(
str(ErrorList([example])),
'<ul class="errorlist"><li>Example of link: '
- '&lt;a href=&quot;http://www.example.com/&quot;&gt;example&lt;/a&gt;</li></ul>'
+ "&lt;a href=&quot;http://www.example.com/&quot;&gt;example&lt;/a&gt;</li></ul>",
)
self.assertHTMLEqual(
str(ErrorList([mark_safe(example)])),
'<ul class="errorlist"><li>Example of link: '
- '<a href="http://www.example.com/">example</a></li></ul>'
+ '<a href="http://www.example.com/">example</a></li></ul>',
)
self.assertHTMLEqual(
- str(ErrorDict({'name': example})),
+ str(ErrorDict({"name": example})),
'<ul class="errorlist"><li>nameExample of link: '
- '&lt;a href=&quot;http://www.example.com/&quot;&gt;example&lt;/a&gt;</li></ul>'
+ "&lt;a href=&quot;http://www.example.com/&quot;&gt;example&lt;/a&gt;</li></ul>",
)
self.assertHTMLEqual(
- str(ErrorDict({'name': mark_safe(example)})),
+ str(ErrorDict({"name": mark_safe(example)})),
'<ul class="errorlist"><li>nameExample of link: '
- '<a href="http://www.example.com/">example</a></li></ul>'
+ '<a href="http://www.example.com/">example</a></li></ul>',
)
def test_error_dict_copy(self):
e = ErrorDict()
- e['__all__'] = ErrorList([
- ValidationError(
- message='message %(i)s',
- params={'i': 1},
- ),
- ValidationError(
- message='message %(i)s',
- params={'i': 2},
- ),
- ])
+ e["__all__"] = ErrorList(
+ [
+ ValidationError(
+ message="message %(i)s",
+ params={"i": 1},
+ ),
+ ValidationError(
+ message="message %(i)s",
+ params={"i": 2},
+ ),
+ ]
+ )
e_copy = copy.copy(e)
self.assertEqual(e, e_copy)
@@ -155,56 +176,70 @@ class FormsUtilsTestCase(SimpleTestCase):
def test_error_dict_html_safe(self):
e = ErrorDict()
- e['username'] = 'Invalid username.'
- self.assertTrue(hasattr(ErrorDict, '__html__'))
+ e["username"] = "Invalid username."
+ self.assertTrue(hasattr(ErrorDict, "__html__"))
self.assertEqual(str(e), e.__html__())
def test_error_list_html_safe(self):
- e = ErrorList(['Invalid username.'])
- self.assertTrue(hasattr(ErrorList, '__html__'))
+ e = ErrorList(["Invalid username."])
+ self.assertTrue(hasattr(ErrorList, "__html__"))
self.assertEqual(str(e), e.__html__())
def test_error_dict_is_dict(self):
self.assertIsInstance(ErrorDict(), dict)
def test_error_dict_is_json_serializable(self):
- init_errors = ErrorDict([
- ('__all__', ErrorList([
- ValidationError('Sorry this form only works on leap days.')
- ])),
- ('name', ErrorList([ValidationError('This field is required.')])),
- ])
- min_value_error_list = ErrorList([
- ValidationError('Ensure this value is greater than or equal to 0.')
- ])
+ init_errors = ErrorDict(
+ [
+ (
+ "__all__",
+ ErrorList(
+ [ValidationError("Sorry this form only works on leap days.")]
+ ),
+ ),
+ ("name", ErrorList([ValidationError("This field is required.")])),
+ ]
+ )
+ min_value_error_list = ErrorList(
+ [ValidationError("Ensure this value is greater than or equal to 0.")]
+ )
e = ErrorDict(
init_errors,
- date=ErrorList([
- ErrorDict({
- 'day': min_value_error_list,
- 'month': min_value_error_list,
- 'year': min_value_error_list,
- }),
- ]),
- )
- e['renderer'] = ErrorList([
- ValidationError(
- 'Select a valid choice. That choice is not one of the '
- 'available choices.'
+ date=ErrorList(
+ [
+ ErrorDict(
+ {
+ "day": min_value_error_list,
+ "month": min_value_error_list,
+ "year": min_value_error_list,
+ }
+ ),
+ ]
),
- ])
- self.assertJSONEqual(json.dumps(e), {
- '__all__': ['Sorry this form only works on leap days.'],
- 'name': ['This field is required.'],
- 'date': [
- {
- 'day': ['Ensure this value is greater than or equal to 0.'],
- 'month': ['Ensure this value is greater than or equal to 0.'],
- 'year': ['Ensure this value is greater than or equal to 0.'],
- },
- ],
- 'renderer': [
- 'Select a valid choice. That choice is not one of the '
- 'available choices.'
- ],
- })
+ )
+ e["renderer"] = ErrorList(
+ [
+ ValidationError(
+ "Select a valid choice. That choice is not one of the "
+ "available choices."
+ ),
+ ]
+ )
+ self.assertJSONEqual(
+ json.dumps(e),
+ {
+ "__all__": ["Sorry this form only works on leap days."],
+ "name": ["This field is required."],
+ "date": [
+ {
+ "day": ["Ensure this value is greater than or equal to 0."],
+ "month": ["Ensure this value is greater than or equal to 0."],
+ "year": ["Ensure this value is greater than or equal to 0."],
+ },
+ ],
+ "renderer": [
+ "Select a valid choice. That choice is not one of the "
+ "available choices."
+ ],
+ },
+ )
diff --git a/tests/forms_tests/tests/test_validators.py b/tests/forms_tests/tests/test_validators.py
index 2f26bbfbb7..731e1c9817 100644
--- a/tests/forms_tests/tests/test_validators.py
+++ b/tests/forms_tests/tests/test_validators.py
@@ -16,40 +16,42 @@ class TestFieldWithValidators(TestCase):
validators=[
validators.validate_integer,
validators.validate_email,
- ]
+ ],
)
string = forms.CharField(
max_length=50,
validators=[
validators.RegexValidator(
- regex='^[a-zA-Z]*$',
+ regex="^[a-zA-Z]*$",
message="Letters only.",
)
- ]
+ ],
)
ignore_case_string = forms.CharField(
max_length=50,
validators=[
validators.RegexValidator(
- regex='^[a-z]*$',
+ regex="^[a-z]*$",
message="Letters only.",
flags=re.IGNORECASE,
)
- ]
+ ],
)
- form = UserForm({
- 'full_name': 'not int nor mail',
- 'string': '2 is not correct',
- 'ignore_case_string': "IgnORE Case strIng",
- })
+ form = UserForm(
+ {
+ "full_name": "not int nor mail",
+ "string": "2 is not correct",
+ "ignore_case_string": "IgnORE Case strIng",
+ }
+ )
with self.assertRaises(ValidationError) as e:
- form.fields['full_name'].clean('not int nor mail')
+ form.fields["full_name"].clean("not int nor mail")
self.assertEqual(2, len(e.exception.messages))
self.assertFalse(form.is_valid())
- self.assertEqual(form.errors['string'], ["Letters only."])
- self.assertEqual(form.errors['string'], ["Letters only."])
+ self.assertEqual(form.errors["string"], ["Letters only."])
+ self.assertEqual(form.errors["string"], ["Letters only."])
def test_field_validators_can_be_any_iterable(self):
class UserForm(forms.Form):
@@ -58,39 +60,42 @@ class TestFieldWithValidators(TestCase):
validators=(
validators.validate_integer,
validators.validate_email,
- )
+ ),
)
- form = UserForm({'full_name': 'not int nor mail'})
+ form = UserForm({"full_name": "not int nor mail"})
self.assertFalse(form.is_valid())
- self.assertEqual(form.errors['full_name'], ['Enter a valid integer.', 'Enter a valid email address.'])
+ self.assertEqual(
+ form.errors["full_name"],
+ ["Enter a valid integer.", "Enter a valid email address."],
+ )
class ValidatorCustomMessageTests(TestCase):
def test_value_placeholder_with_char_field(self):
cases = [
- (validators.validate_integer, '-42.5', 'invalid'),
- (validators.validate_email, 'a', 'invalid'),
- (validators.validate_email, 'a@b\n.com', 'invalid'),
- (validators.validate_email, 'a\n@b.com', 'invalid'),
- (validators.validate_slug, '你 好', 'invalid'),
- (validators.validate_unicode_slug, '你 好', 'invalid'),
- (validators.validate_ipv4_address, '256.1.1.1', 'invalid'),
- (validators.validate_ipv6_address, '1:2', 'invalid'),
- (validators.validate_ipv46_address, '256.1.1.1', 'invalid'),
- (validators.validate_comma_separated_integer_list, 'a,b,c', 'invalid'),
- (validators.int_list_validator(), '-1,2,3', 'invalid'),
- (validators.MaxLengthValidator(10), 11 * 'x', 'max_length'),
- (validators.MinLengthValidator(10), 9 * 'x', 'min_length'),
- (validators.URLValidator(), 'no_scheme', 'invalid'),
- (validators.URLValidator(), 'http://test[.com', 'invalid'),
- (validators.URLValidator(), 'http://[::1:2::3]/', 'invalid'),
+ (validators.validate_integer, "-42.5", "invalid"),
+ (validators.validate_email, "a", "invalid"),
+ (validators.validate_email, "a@b\n.com", "invalid"),
+ (validators.validate_email, "a\n@b.com", "invalid"),
+ (validators.validate_slug, "你 好", "invalid"),
+ (validators.validate_unicode_slug, "你 好", "invalid"),
+ (validators.validate_ipv4_address, "256.1.1.1", "invalid"),
+ (validators.validate_ipv6_address, "1:2", "invalid"),
+ (validators.validate_ipv46_address, "256.1.1.1", "invalid"),
+ (validators.validate_comma_separated_integer_list, "a,b,c", "invalid"),
+ (validators.int_list_validator(), "-1,2,3", "invalid"),
+ (validators.MaxLengthValidator(10), 11 * "x", "max_length"),
+ (validators.MinLengthValidator(10), 9 * "x", "min_length"),
+ (validators.URLValidator(), "no_scheme", "invalid"),
+ (validators.URLValidator(), "http://test[.com", "invalid"),
+ (validators.URLValidator(), "http://[::1:2::3]/", "invalid"),
(
validators.URLValidator(),
- 'http://' + '.'.join(['a' * 35 for _ in range(9)]),
- 'invalid',
+ "http://" + ".".join(["a" * 35 for _ in range(9)]),
+ "invalid",
),
- (validators.RegexValidator('[0-9]+'), 'xxxxxx', 'invalid'),
+ (validators.RegexValidator("[0-9]+"), "xxxxxx", "invalid"),
]
for validator, value, code in cases:
if isinstance(validator, types.FunctionType):
@@ -98,71 +103,74 @@ class ValidatorCustomMessageTests(TestCase):
else:
name = type(validator).__name__
with self.subTest(name, value=value):
+
class MyForm(forms.Form):
field = forms.CharField(
validators=[validator],
- error_messages={code: '%(value)s'},
+ error_messages={code: "%(value)s"},
)
- form = MyForm({'field': value})
+ form = MyForm({"field": value})
self.assertIs(form.is_valid(), False)
- self.assertEqual(form.errors, {'field': [value]})
+ self.assertEqual(form.errors, {"field": [value]})
def test_value_placeholder_with_null_character(self):
class MyForm(forms.Form):
field = forms.CharField(
- error_messages={'null_characters_not_allowed': '%(value)s'},
+ error_messages={"null_characters_not_allowed": "%(value)s"},
)
- form = MyForm({'field': 'a\0b'})
+ form = MyForm({"field": "a\0b"})
self.assertIs(form.is_valid(), False)
- self.assertEqual(form.errors, {'field': ['a\x00b']})
+ self.assertEqual(form.errors, {"field": ["a\x00b"]})
def test_value_placeholder_with_integer_field(self):
cases = [
- (validators.MaxValueValidator(0), 1, 'max_value'),
- (validators.MinValueValidator(0), -1, 'min_value'),
- (validators.URLValidator(), '1', 'invalid'),
+ (validators.MaxValueValidator(0), 1, "max_value"),
+ (validators.MinValueValidator(0), -1, "min_value"),
+ (validators.URLValidator(), "1", "invalid"),
]
for validator, value, code in cases:
with self.subTest(type(validator).__name__, value=value):
+
class MyForm(forms.Form):
field = forms.IntegerField(
validators=[validator],
- error_messages={code: '%(value)s'},
+ error_messages={code: "%(value)s"},
)
- form = MyForm({'field': value})
+ form = MyForm({"field": value})
self.assertIs(form.is_valid(), False)
- self.assertEqual(form.errors, {'field': [str(value)]})
+ self.assertEqual(form.errors, {"field": [str(value)]})
def test_value_placeholder_with_decimal_field(self):
cases = [
- ('NaN', 'invalid'),
- ('123', 'max_digits'),
- ('0.12', 'max_decimal_places'),
- ('12', 'max_whole_digits'),
+ ("NaN", "invalid"),
+ ("123", "max_digits"),
+ ("0.12", "max_decimal_places"),
+ ("12", "max_whole_digits"),
]
for value, code in cases:
with self.subTest(value=value):
+
class MyForm(forms.Form):
field = forms.DecimalField(
max_digits=2,
decimal_places=1,
- error_messages={code: '%(value)s'},
+ error_messages={code: "%(value)s"},
)
- form = MyForm({'field': value})
+ form = MyForm({"field": value})
self.assertIs(form.is_valid(), False)
- self.assertEqual(form.errors, {'field': [value]})
+ self.assertEqual(form.errors, {"field": [value]})
def test_value_placeholder_with_file_field(self):
class MyForm(forms.Form):
field = forms.FileField(
validators=[validators.validate_image_file_extension],
- error_messages={'invalid_extension': '%(value)s'},
+ error_messages={"invalid_extension": "%(value)s"},
)
- form = MyForm(files={'field': SimpleUploadedFile('myfile.txt', b'abc')})
+ form = MyForm(files={"field": SimpleUploadedFile("myfile.txt", b"abc")})
self.assertIs(form.is_valid(), False)
- self.assertEqual(form.errors, {'field': ['myfile.txt']})
+ self.assertEqual(form.errors, {"field": ["myfile.txt"]})
diff --git a/tests/forms_tests/tests/test_widgets.py b/tests/forms_tests/tests/test_widgets.py
index f429f92547..e28c1f2462 100644
--- a/tests/forms_tests/tests/test_widgets.py
+++ b/tests/forms_tests/tests/test_widgets.py
@@ -5,18 +5,21 @@ from django.urls import reverse
from ..models import Article
-@override_settings(ROOT_URLCONF='forms_tests.urls')
+@override_settings(ROOT_URLCONF="forms_tests.urls")
class LiveWidgetTests(AdminSeleniumTestCase):
- available_apps = ['forms_tests'] + AdminSeleniumTestCase.available_apps
+ available_apps = ["forms_tests"] + AdminSeleniumTestCase.available_apps
def test_textarea_trailing_newlines(self):
"""
A roundtrip on a ModelForm doesn't alter the TextField value
"""
from selenium.webdriver.common.by import By
+
article = Article.objects.create(content="\nTst\n")
- self.selenium.get(self.live_server_url + reverse('article_form', args=[article.pk]))
- self.selenium.find_element(By.ID, 'submit').click()
+ self.selenium.get(
+ self.live_server_url + reverse("article_form", args=[article.pk])
+ )
+ self.selenium.find_element(By.ID, "submit").click()
article = Article.objects.get(pk=article.pk)
self.assertEqual(article.content, "\r\nTst\r\n")
diff --git a/tests/forms_tests/tests/tests.py b/tests/forms_tests/tests/tests.py
index 24ae09a800..5a860037e5 100644
--- a/tests/forms_tests/tests/tests.py
+++ b/tests/forms_tests/tests/tests.py
@@ -7,8 +7,13 @@ from django.forms.models import ModelFormMetaclass
from django.test import SimpleTestCase, TestCase
from ..models import (
- BoundaryModel, ChoiceFieldModel, ChoiceModel, ChoiceOptionModel, Defaults,
- FileModel, OptionalMultiChoiceModel,
+ BoundaryModel,
+ ChoiceFieldModel,
+ ChoiceModel,
+ ChoiceOptionModel,
+ Defaults,
+ FileModel,
+ OptionalMultiChoiceModel,
)
from . import jinja2_tests
@@ -16,39 +21,39 @@ from . import jinja2_tests
class ChoiceFieldForm(ModelForm):
class Meta:
model = ChoiceFieldModel
- fields = '__all__'
+ fields = "__all__"
class OptionalMultiChoiceModelForm(ModelForm):
class Meta:
model = OptionalMultiChoiceModel
- fields = '__all__'
+ fields = "__all__"
class ChoiceFieldExclusionForm(ModelForm):
multi_choice = CharField(max_length=50)
class Meta:
- exclude = ['multi_choice']
+ exclude = ["multi_choice"]
model = ChoiceFieldModel
class EmptyCharLabelChoiceForm(ModelForm):
class Meta:
model = ChoiceModel
- fields = ['name', 'choice']
+ fields = ["name", "choice"]
class EmptyIntegerLabelChoiceForm(ModelForm):
class Meta:
model = ChoiceModel
- fields = ['name', 'choice_integer']
+ fields = ["name", "choice_integer"]
class EmptyCharLabelNoneChoiceForm(ModelForm):
class Meta:
model = ChoiceModel
- fields = ['name', 'choice_string_w_none']
+ fields = ["name", "choice_string_w_none"]
class FileForm(Form):
@@ -59,31 +64,36 @@ class TestTicket14567(TestCase):
"""
The return values of ModelMultipleChoiceFields are QuerySets
"""
+
def test_empty_queryset_return(self):
"If a model's ManyToManyField has blank=True and is saved with no data, a queryset is returned."
- option = ChoiceOptionModel.objects.create(name='default')
- form = OptionalMultiChoiceModelForm({'multi_choice_optional': '', 'multi_choice': [option.pk]})
+ option = ChoiceOptionModel.objects.create(name="default")
+ form = OptionalMultiChoiceModelForm(
+ {"multi_choice_optional": "", "multi_choice": [option.pk]}
+ )
self.assertTrue(form.is_valid())
# The empty value is a QuerySet
- self.assertIsInstance(form.cleaned_data['multi_choice_optional'], models.query.QuerySet)
+ self.assertIsInstance(
+ form.cleaned_data["multi_choice_optional"], models.query.QuerySet
+ )
# While we're at it, test whether a QuerySet is returned if there *is* a value.
- self.assertIsInstance(form.cleaned_data['multi_choice'], models.query.QuerySet)
+ self.assertIsInstance(form.cleaned_data["multi_choice"], models.query.QuerySet)
class ModelFormCallableModelDefault(TestCase):
def test_no_empty_option(self):
"If a model's ForeignKey has blank=False and a default, no empty option is created (Refs #10792)."
- option = ChoiceOptionModel.objects.create(name='default')
+ option = ChoiceOptionModel.objects.create(name="default")
- choices = list(ChoiceFieldForm().fields['choice'].choices)
+ choices = list(ChoiceFieldForm().fields["choice"].choices)
self.assertEqual(len(choices), 1)
self.assertEqual(choices[0], (option.pk, str(option)))
def test_callable_initial_value(self):
"The initial value for a callable default returning a queryset is the pk (refs #13769)"
- ChoiceOptionModel.objects.create(id=1, name='default')
- ChoiceOptionModel.objects.create(id=2, name='option 2')
- ChoiceOptionModel.objects.create(id=3, name='option 3')
+ ChoiceOptionModel.objects.create(id=1, name="default")
+ ChoiceOptionModel.objects.create(id=2, name="option 2")
+ ChoiceOptionModel.objects.create(id=3, name="option 3")
self.assertHTMLEqual(
ChoiceFieldForm().as_p(),
"""<p><label for="id_choice">Choice:</label> <select name="choice" id="id_choice">
@@ -107,21 +117,25 @@ class ModelFormCallableModelDefault(TestCase):
<option value="1" selected>ChoiceOption 1</option>
<option value="2">ChoiceOption 2</option>
<option value="3">ChoiceOption 3</option>
-</select><input type="hidden" name="initial-multi_choice_int" value="1" id="initial-id_multi_choice_int_0"></p>"""
+</select><input type="hidden" name="initial-multi_choice_int" value="1" id="initial-id_multi_choice_int_0"></p>""",
)
def test_initial_instance_value(self):
"Initial instances for model fields may also be instances (refs #7287)"
- ChoiceOptionModel.objects.create(id=1, name='default')
- obj2 = ChoiceOptionModel.objects.create(id=2, name='option 2')
- obj3 = ChoiceOptionModel.objects.create(id=3, name='option 3')
+ ChoiceOptionModel.objects.create(id=1, name="default")
+ obj2 = ChoiceOptionModel.objects.create(id=2, name="option 2")
+ obj3 = ChoiceOptionModel.objects.create(id=3, name="option 3")
self.assertHTMLEqual(
- ChoiceFieldForm(initial={
- 'choice': obj2,
- 'choice_int': obj2,
- 'multi_choice': [obj2, obj3],
- 'multi_choice_int': ChoiceOptionModel.objects.exclude(name="default"),
- }).as_p(),
+ ChoiceFieldForm(
+ initial={
+ "choice": obj2,
+ "choice_int": obj2,
+ "multi_choice": [obj2, obj3],
+ "multi_choice_int": ChoiceOptionModel.objects.exclude(
+ name="default"
+ ),
+ }
+ ).as_p(),
"""<p><label for="id_choice">Choice:</label> <select name="choice" id="id_choice">
<option value="1">ChoiceOption 1</option>
<option value="2" selected>ChoiceOption 2</option>
@@ -145,19 +159,24 @@ class ModelFormCallableModelDefault(TestCase):
<option value="2" selected>ChoiceOption 2</option>
<option value="3" selected>ChoiceOption 3</option>
</select><input type="hidden" name="initial-multi_choice_int" value="2" id="initial-id_multi_choice_int_0">
-<input type="hidden" name="initial-multi_choice_int" value="3" id="initial-id_multi_choice_int_1"></p>"""
+<input type="hidden" name="initial-multi_choice_int" value="3" id="initial-id_multi_choice_int_1"></p>""",
)
class FormsModelTestCase(TestCase):
def test_unicode_filename(self):
# FileModel with Unicode filename and data #########################
- file1 = SimpleUploadedFile('我隻氣墊船裝滿晒鱔.txt', 'मेरी मँडराने वाली नाव सर्पमीनों से भरी ह'.encode())
- f = FileForm(data={}, files={'file1': file1}, auto_id=False)
+ file1 = SimpleUploadedFile(
+ "我隻氣墊船裝滿晒鱔.txt", "मेरी मँडराने वाली नाव सर्पमीनों से भरी ह".encode()
+ )
+ f = FileForm(data={}, files={"file1": file1}, auto_id=False)
self.assertTrue(f.is_valid())
- self.assertIn('file1', f.cleaned_data)
- m = FileModel.objects.create(file=f.cleaned_data['file1'])
- self.assertEqual(m.file.name, 'tests/\u6211\u96bb\u6c23\u588a\u8239\u88dd\u6eff\u6652\u9c54.txt')
+ self.assertIn("file1", f.cleaned_data)
+ m = FileModel.objects.create(file=f.cleaned_data["file1"])
+ self.assertEqual(
+ m.file.name,
+ "tests/\u6211\u96bb\u6c23\u588a\u8239\u88dd\u6eff\u6652\u9c54.txt",
+ )
m.delete()
def test_boundary_conditions(self):
@@ -165,13 +184,13 @@ class FormsModelTestCase(TestCase):
class BoundaryForm(ModelForm):
class Meta:
model = BoundaryModel
- fields = '__all__'
+ fields = "__all__"
- f = BoundaryForm({'positive_integer': 100})
+ f = BoundaryForm({"positive_integer": 100})
self.assertTrue(f.is_valid())
- f = BoundaryForm({'positive_integer': 0})
+ f = BoundaryForm({"positive_integer": 0})
self.assertTrue(f.is_valid())
- f = BoundaryForm({'positive_integer': -100})
+ f = BoundaryForm({"positive_integer": -100})
self.assertFalse(f.is_valid())
def test_formfield_initial(self):
@@ -181,22 +200,26 @@ class FormsModelTestCase(TestCase):
class DefaultsForm(ModelForm):
class Meta:
model = Defaults
- fields = '__all__'
+ fields = "__all__"
- self.assertEqual(DefaultsForm().fields['name'].initial, 'class default value')
- self.assertEqual(DefaultsForm().fields['def_date'].initial, datetime.date(1980, 1, 1))
- self.assertEqual(DefaultsForm().fields['value'].initial, 42)
- r1 = DefaultsForm()['callable_default'].as_widget()
- r2 = DefaultsForm()['callable_default'].as_widget()
+ self.assertEqual(DefaultsForm().fields["name"].initial, "class default value")
+ self.assertEqual(
+ DefaultsForm().fields["def_date"].initial, datetime.date(1980, 1, 1)
+ )
+ self.assertEqual(DefaultsForm().fields["value"].initial, 42)
+ r1 = DefaultsForm()["callable_default"].as_widget()
+ r2 = DefaultsForm()["callable_default"].as_widget()
self.assertNotEqual(r1, r2)
# In a ModelForm that is passed an instance, the initial values come from the
# instance's values, not the model's defaults.
- foo_instance = Defaults(name='instance value', def_date=datetime.date(1969, 4, 4), value=12)
+ foo_instance = Defaults(
+ name="instance value", def_date=datetime.date(1969, 4, 4), value=12
+ )
instance_form = DefaultsForm(instance=foo_instance)
- self.assertEqual(instance_form.initial['name'], 'instance value')
- self.assertEqual(instance_form.initial['def_date'], datetime.date(1969, 4, 4))
- self.assertEqual(instance_form.initial['value'], 12)
+ self.assertEqual(instance_form.initial["name"], "instance value")
+ self.assertEqual(instance_form.initial["def_date"], datetime.date(1969, 4, 4))
+ self.assertEqual(instance_form.initial["value"], 12)
from django.forms import CharField
@@ -205,13 +228,15 @@ class FormsModelTestCase(TestCase):
class Meta:
model = Defaults
- exclude = ['name', 'callable_default']
+ exclude = ["name", "callable_default"]
- f = ExcludingForm({'name': 'Hello', 'value': 99, 'def_date': datetime.date(1999, 3, 2)})
+ f = ExcludingForm(
+ {"name": "Hello", "value": 99, "def_date": datetime.date(1999, 3, 2)}
+ )
self.assertTrue(f.is_valid())
- self.assertEqual(f.cleaned_data['name'], 'Hello')
+ self.assertEqual(f.cleaned_data["name"], "Hello")
obj = f.save()
- self.assertEqual(obj.name, 'class default value')
+ self.assertEqual(obj.name, "class default value")
self.assertEqual(obj.value, 99)
self.assertEqual(obj.def_date, datetime.date(1999, 3, 2))
@@ -221,19 +246,20 @@ class RelatedModelFormTests(SimpleTestCase):
"""
Test for issue 10405
"""
+
class A(models.Model):
ref = models.ForeignKey("B", models.CASCADE)
class Meta:
model = A
- fields = '__all__'
+ fields = "__all__"
msg = (
"Cannot create form field for 'ref' yet, because "
"its related model 'B' has not been loaded yet"
)
with self.assertRaisesMessage(ValueError, msg):
- ModelFormMetaclass('Form', (ModelForm,), {'Meta': Meta})
+ ModelFormMetaclass("Form", (ModelForm,), {"Meta": Meta})
class B(models.Model):
pass
@@ -242,6 +268,7 @@ class RelatedModelFormTests(SimpleTestCase):
"""
Test for issue 10405
"""
+
class C(models.Model):
ref = models.ForeignKey("D", models.CASCADE)
@@ -250,38 +277,45 @@ class RelatedModelFormTests(SimpleTestCase):
class Meta:
model = C
- fields = '__all__'
+ fields = "__all__"
- self.assertTrue(issubclass(ModelFormMetaclass('Form', (ModelForm,), {'Meta': Meta}), ModelForm))
+ self.assertTrue(
+ issubclass(
+ ModelFormMetaclass("Form", (ModelForm,), {"Meta": Meta}), ModelForm
+ )
+ )
class ManyToManyExclusionTestCase(TestCase):
def test_m2m_field_exclusion(self):
# Issue 12337. save_instance should honor the passed-in exclude keyword.
- opt1 = ChoiceOptionModel.objects.create(id=1, name='default')
- opt2 = ChoiceOptionModel.objects.create(id=2, name='option 2')
- opt3 = ChoiceOptionModel.objects.create(id=3, name='option 3')
+ opt1 = ChoiceOptionModel.objects.create(id=1, name="default")
+ opt2 = ChoiceOptionModel.objects.create(id=2, name="option 2")
+ opt3 = ChoiceOptionModel.objects.create(id=3, name="option 3")
initial = {
- 'choice': opt1,
- 'choice_int': opt1,
+ "choice": opt1,
+ "choice_int": opt1,
}
data = {
- 'choice': opt2.pk,
- 'choice_int': opt2.pk,
- 'multi_choice': 'string data!',
- 'multi_choice_int': [opt1.pk],
+ "choice": opt2.pk,
+ "choice_int": opt2.pk,
+ "multi_choice": "string data!",
+ "multi_choice_int": [opt1.pk],
}
instance = ChoiceFieldModel.objects.create(**initial)
instance.multi_choice.set([opt2, opt3])
instance.multi_choice_int.set([opt2, opt3])
form = ChoiceFieldExclusionForm(data=data, instance=instance)
self.assertTrue(form.is_valid())
- self.assertEqual(form.cleaned_data['multi_choice'], data['multi_choice'])
+ self.assertEqual(form.cleaned_data["multi_choice"], data["multi_choice"])
form.save()
- self.assertEqual(form.instance.choice.pk, data['choice'])
- self.assertEqual(form.instance.choice_int.pk, data['choice_int'])
+ self.assertEqual(form.instance.choice.pk, data["choice"])
+ self.assertEqual(form.instance.choice_int.pk, data["choice_int"])
self.assertEqual(list(form.instance.multi_choice.all()), [opt2, opt3])
- self.assertEqual([obj.pk for obj in form.instance.multi_choice_int.all()], data['multi_choice_int'])
+ self.assertEqual(
+ [obj.pk for obj in form.instance.multi_choice_int.all()],
+ data["multi_choice_int"],
+ )
class EmptyLabelTestCase(TestCase):
@@ -294,7 +328,7 @@ class EmptyLabelTestCase(TestCase):
<option value="" selected>No Preference</option>
<option value="f">Foo</option>
<option value="b">Bar</option>
-</select></p>"""
+</select></p>""",
)
def test_empty_field_char_none(self):
@@ -307,25 +341,27 @@ class EmptyLabelTestCase(TestCase):
<option value="" selected>No Preference</option>
<option value="f">Foo</option>
<option value="b">Bar</option>
-</select></p>"""
+</select></p>""",
)
def test_save_empty_label_forms(self):
# Saving a form with a blank choice results in the expected
# value being stored in the database.
tests = [
- (EmptyCharLabelNoneChoiceForm, 'choice_string_w_none', None),
- (EmptyIntegerLabelChoiceForm, 'choice_integer', None),
- (EmptyCharLabelChoiceForm, 'choice', ''),
+ (EmptyCharLabelNoneChoiceForm, "choice_string_w_none", None),
+ (EmptyIntegerLabelChoiceForm, "choice_integer", None),
+ (EmptyCharLabelChoiceForm, "choice", ""),
]
for form, key, expected in tests:
with self.subTest(form=form):
- f = form({'name': 'some-key', key: ''})
+ f = form({"name": "some-key", key: ""})
self.assertTrue(f.is_valid())
m = f.save()
self.assertEqual(expected, getattr(m, key))
- self.assertEqual('No Preference', getattr(m, 'get_{}_display'.format(key))())
+ self.assertEqual(
+ "No Preference", getattr(m, "get_{}_display".format(key))()
+ )
def test_empty_field_integer(self):
f = EmptyIntegerLabelChoiceForm()
@@ -337,16 +373,16 @@ class EmptyLabelTestCase(TestCase):
<option value="" selected>No Preference</option>
<option value="1">Foo</option>
<option value="2">Bar</option>
-</select></p>"""
+</select></p>""",
)
def test_get_display_value_on_none(self):
- m = ChoiceModel.objects.create(name='test', choice='', choice_integer=None)
+ m = ChoiceModel.objects.create(name="test", choice="", choice_integer=None)
self.assertIsNone(m.choice_integer)
- self.assertEqual('No Preference', m.get_choice_integer_display())
+ self.assertEqual("No Preference", m.get_choice_integer_display())
def test_html_rendering_of_prepopulated_models(self):
- none_model = ChoiceModel(name='none-test', choice_integer=None)
+ none_model = ChoiceModel(name="none-test", choice_integer=None)
f = EmptyIntegerLabelChoiceForm(instance=none_model)
self.assertHTMLEqual(
f.as_p(),
@@ -357,10 +393,10 @@ class EmptyLabelTestCase(TestCase):
<option value="" selected>No Preference</option>
<option value="1">Foo</option>
<option value="2">Bar</option>
-</select></p>"""
+</select></p>""",
)
- foo_model = ChoiceModel(name='foo-test', choice_integer=1)
+ foo_model = ChoiceModel(name="foo-test", choice_integer=1)
f = EmptyIntegerLabelChoiceForm(instance=foo_model)
self.assertHTMLEqual(
f.as_p(),
@@ -371,7 +407,7 @@ class EmptyLabelTestCase(TestCase):
<option value="">No Preference</option>
<option value="1" selected>Foo</option>
<option value="2">Bar</option>
-</select></p>"""
+</select></p>""",
)
diff --git a/tests/forms_tests/urls.py b/tests/forms_tests/urls.py
index 7e27927099..4063568a81 100644
--- a/tests/forms_tests/urls.py
+++ b/tests/forms_tests/urls.py
@@ -3,6 +3,6 @@ from django.urls import path
from .views import ArticleFormView, form_view
urlpatterns = [
- path('form_view/', form_view, name='form_view'),
- path('model_form/<int:pk>/', ArticleFormView.as_view(), name='article_form'),
+ path("form_view/", form_view, name="form_view"),
+ path("model_form/<int:pk>/", ArticleFormView.as_view(), name="article_form"),
]
diff --git a/tests/forms_tests/views.py b/tests/forms_tests/views.py
index 20f1bf161d..b03472824d 100644
--- a/tests/forms_tests/views.py
+++ b/tests/forms_tests/views.py
@@ -11,12 +11,12 @@ class ArticleForm(forms.ModelForm):
class Meta:
model = Article
- fields = '__all__'
+ fields = "__all__"
class ArticleFormView(UpdateView):
model = Article
- success_url = '/'
+ success_url = "/"
form_class = ArticleForm
@@ -24,6 +24,6 @@ def form_view(request):
class Form(forms.Form):
number = forms.FloatField()
- template = Template('<html>{{ form }}</html>')
- context = Context({'form': Form()})
+ template = Template("<html>{{ form }}</html>")
+ context = Context({"form": Form()})
return HttpResponse(template.render(context))
diff --git a/tests/forms_tests/widget_tests/base.py b/tests/forms_tests/widget_tests/base.py
index 339d78bc71..c29099abf2 100644
--- a/tests/forms_tests/widget_tests/base.py
+++ b/tests/forms_tests/widget_tests/base.py
@@ -8,24 +8,32 @@ except ImportError:
class WidgetTest(SimpleTestCase):
- beatles = (('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))
+ beatles = (("J", "John"), ("P", "Paul"), ("G", "George"), ("R", "Ringo"))
@classmethod
def setUpClass(cls):
cls.django_renderer = DjangoTemplates()
cls.jinja2_renderer = Jinja2() if jinja2 else None
- cls.renderers = [cls.django_renderer] + ([cls.jinja2_renderer] if cls.jinja2_renderer else [])
+ cls.renderers = [cls.django_renderer] + (
+ [cls.jinja2_renderer] if cls.jinja2_renderer else []
+ )
super().setUpClass()
- def check_html(self, widget, name, value, html='', attrs=None, strict=False, **kwargs):
+ def check_html(
+ self, widget, name, value, html="", attrs=None, strict=False, **kwargs
+ ):
assertEqual = self.assertEqual if strict else self.assertHTMLEqual
if self.jinja2_renderer:
- output = widget.render(name, value, attrs=attrs, renderer=self.jinja2_renderer, **kwargs)
+ output = widget.render(
+ name, value, attrs=attrs, renderer=self.jinja2_renderer, **kwargs
+ )
# Django escapes quotes with '&quot;' while Jinja2 uses '&#34;'.
- output = output.replace('&#34;', '&quot;')
+ output = output.replace("&#34;", "&quot;")
# Django escapes single quotes with '&#x27;' while Jinja2 uses '&#39;'.
- output = output.replace('&#39;', '&#x27;')
+ output = output.replace("&#39;", "&#x27;")
assertEqual(output, html)
- output = widget.render(name, value, attrs=attrs, renderer=self.django_renderer, **kwargs)
+ output = widget.render(
+ name, value, attrs=attrs, renderer=self.django_renderer, **kwargs
+ )
assertEqual(output, html)
diff --git a/tests/forms_tests/widget_tests/test_checkboxinput.py b/tests/forms_tests/widget_tests/test_checkboxinput.py
index 8dba2178c9..0f65e876df 100644
--- a/tests/forms_tests/widget_tests/test_checkboxinput.py
+++ b/tests/forms_tests/widget_tests/test_checkboxinput.py
@@ -7,18 +7,26 @@ class CheckboxInputTest(WidgetTest):
widget = CheckboxInput()
def test_render_empty(self):
- self.check_html(self.widget, 'is_cool', '', html='<input type="checkbox" name="is_cool">')
+ self.check_html(
+ self.widget, "is_cool", "", html='<input type="checkbox" name="is_cool">'
+ )
def test_render_none(self):
- self.check_html(self.widget, 'is_cool', None, html='<input type="checkbox" name="is_cool">')
+ self.check_html(
+ self.widget, "is_cool", None, html='<input type="checkbox" name="is_cool">'
+ )
def test_render_false(self):
- self.check_html(self.widget, 'is_cool', False, html='<input type="checkbox" name="is_cool">')
+ self.check_html(
+ self.widget, "is_cool", False, html='<input type="checkbox" name="is_cool">'
+ )
def test_render_true(self):
self.check_html(
- self.widget, 'is_cool', True,
- html='<input checked type="checkbox" name="is_cool">'
+ self.widget,
+ "is_cool",
+ True,
+ html='<input checked type="checkbox" name="is_cool">',
)
def test_render_value(self):
@@ -27,7 +35,9 @@ class CheckboxInputTest(WidgetTest):
checkbox and set the 'value' attribute.
"""
self.check_html(
- self.widget, 'is_cool', 'foo',
+ self.widget,
+ "is_cool",
+ "foo",
html='<input checked type="checkbox" name="is_cool" value="foo">',
)
@@ -36,11 +46,15 @@ class CheckboxInputTest(WidgetTest):
Integers are handled by value, not as booleans (#17114).
"""
self.check_html(
- self.widget, 'is_cool', 0,
+ self.widget,
+ "is_cool",
+ 0,
html='<input checked type="checkbox" name="is_cool" value="0">',
)
self.check_html(
- self.widget, 'is_cool', 1,
+ self.widget,
+ "is_cool",
+ 1,
html='<input checked type="checkbox" name="is_cool" value="1">',
)
@@ -49,30 +63,43 @@ class CheckboxInputTest(WidgetTest):
You can pass 'check_test' to the constructor. This is a callable that
takes the value and returns True if the box should be checked.
"""
- widget = CheckboxInput(check_test=lambda value: value.startswith('hello'))
- self.check_html(widget, 'greeting', '', html=(
- '<input type="checkbox" name="greeting">'
- ))
- self.check_html(widget, 'greeting', 'hello', html=(
- '<input checked type="checkbox" name="greeting" value="hello">'
- ))
- self.check_html(widget, 'greeting', 'hello there', html=(
- '<input checked type="checkbox" name="greeting" value="hello there">'
- ))
- self.check_html(widget, 'greeting', 'hello & goodbye', html=(
- '<input checked type="checkbox" name="greeting" value="hello &amp; goodbye">'
- ))
+ widget = CheckboxInput(check_test=lambda value: value.startswith("hello"))
+ self.check_html(
+ widget, "greeting", "", html=('<input type="checkbox" name="greeting">')
+ )
+ self.check_html(
+ widget,
+ "greeting",
+ "hello",
+ html=('<input checked type="checkbox" name="greeting" value="hello">'),
+ )
+ self.check_html(
+ widget,
+ "greeting",
+ "hello there",
+ html=(
+ '<input checked type="checkbox" name="greeting" value="hello there">'
+ ),
+ )
+ self.check_html(
+ widget,
+ "greeting",
+ "hello & goodbye",
+ html=(
+ '<input checked type="checkbox" name="greeting" value="hello &amp; goodbye">'
+ ),
+ )
def test_render_check_exception(self):
"""
Calling check_test() shouldn't swallow exceptions (#17888).
"""
widget = CheckboxInput(
- check_test=lambda value: value.startswith('hello'),
+ check_test=lambda value: value.startswith("hello"),
)
with self.assertRaises(AttributeError):
- widget.render('greeting', True)
+ widget.render("greeting", True)
def test_value_from_datadict(self):
"""
@@ -80,17 +107,19 @@ class CheckboxInputTest(WidgetTest):
the data dictionary (because HTML form submission doesn't send any
result for unchecked checkboxes).
"""
- self.assertFalse(self.widget.value_from_datadict({}, {}, 'testing'))
+ self.assertFalse(self.widget.value_from_datadict({}, {}, "testing"))
def test_value_from_datadict_string_int(self):
- value = self.widget.value_from_datadict({'testing': '0'}, {}, 'testing')
+ value = self.widget.value_from_datadict({"testing": "0"}, {}, "testing")
self.assertIs(value, True)
def test_value_omitted_from_data(self):
- self.assertIs(self.widget.value_omitted_from_data({'field': 'value'}, {}, 'field'), False)
- self.assertIs(self.widget.value_omitted_from_data({}, {}, 'field'), False)
+ self.assertIs(
+ self.widget.value_omitted_from_data({"field": "value"}, {}, "field"), False
+ )
+ self.assertIs(self.widget.value_omitted_from_data({}, {}, "field"), False)
def test_get_context_does_not_mutate_attrs(self):
- attrs = {'checked': False}
- self.widget.get_context('name', True, attrs)
- self.assertIs(attrs['checked'], False)
+ attrs = {"checked": False}
+ self.widget.get_context("name", True, attrs)
+ self.assertIs(attrs["checked"], False)
diff --git a/tests/forms_tests/widget_tests/test_checkboxselectmultiple.py b/tests/forms_tests/widget_tests/test_checkboxselectmultiple.py
index 65025ed748..35db8192ef 100644
--- a/tests/forms_tests/widget_tests/test_checkboxselectmultiple.py
+++ b/tests/forms_tests/widget_tests/test_checkboxselectmultiple.py
@@ -11,31 +11,45 @@ class CheckboxSelectMultipleTest(WidgetTest):
widget = CheckboxSelectMultiple
def test_render_value(self):
- self.check_html(self.widget(choices=self.beatles), 'beatles', ['J'], html="""
+ self.check_html(
+ self.widget(choices=self.beatles),
+ "beatles",
+ ["J"],
+ html="""
<div>
<div><label><input checked type="checkbox" name="beatles" value="J"> John</label></div>
<div><label><input type="checkbox" name="beatles" value="P"> Paul</label></div>
<div><label><input type="checkbox" name="beatles" value="G"> George</label></div>
<div><label><input type="checkbox" name="beatles" value="R"> Ringo</label></div>
</div>
- """)
+ """,
+ )
def test_render_value_multiple(self):
- self.check_html(self.widget(choices=self.beatles), 'beatles', ['J', 'P'], html="""
+ self.check_html(
+ self.widget(choices=self.beatles),
+ "beatles",
+ ["J", "P"],
+ html="""
<div>
<div><label><input checked type="checkbox" name="beatles" value="J"> John</label></div>
<div><label><input checked type="checkbox" name="beatles" value="P"> Paul</label></div>
<div><label><input type="checkbox" name="beatles" value="G"> George</label></div>
<div><label><input type="checkbox" name="beatles" value="R"> Ringo</label></div>
</div>
- """)
+ """,
+ )
def test_render_none(self):
"""
If the value is None, none of the options are selected, even if the
choices have an empty option.
"""
- self.check_html(self.widget(choices=(('', 'Unknown'),) + self.beatles), 'beatles', None, html="""
+ self.check_html(
+ self.widget(choices=(("", "Unknown"),) + self.beatles),
+ "beatles",
+ None,
+ html="""
<div>
<div><label><input type="checkbox" name="beatles" value=""> Unknown</label></div>
<div><label><input type="checkbox" name="beatles" value="J"> John</label></div>
@@ -43,13 +57,14 @@ class CheckboxSelectMultipleTest(WidgetTest):
<div><label><input type="checkbox" name="beatles" value="G"> George</label></div>
<div><label><input type="checkbox" name="beatles" value="R"> Ringo</label></div>
</div>
- """)
+ """,
+ )
def test_nested_choices(self):
nested_choices = (
- ('unknown', 'Unknown'),
- ('Audio', (('vinyl', 'Vinyl'), ('cd', 'CD'))),
- ('Video', (('vhs', 'VHS'), ('dvd', 'DVD'))),
+ ("unknown", "Unknown"),
+ ("Audio", (("vinyl", "Vinyl"), ("cd", "CD"))),
+ ("Video", (("vhs", "VHS"), ("dvd", "DVD"))),
)
html = """
<div id="media">
@@ -71,15 +86,18 @@ class CheckboxSelectMultipleTest(WidgetTest):
</div>
"""
self.check_html(
- self.widget(choices=nested_choices), 'nestchoice', ('vinyl', 'dvd'),
- attrs={'id': 'media'}, html=html,
+ self.widget(choices=nested_choices),
+ "nestchoice",
+ ("vinyl", "dvd"),
+ attrs={"id": "media"},
+ html=html,
)
def test_nested_choices_without_id(self):
nested_choices = (
- ('unknown', 'Unknown'),
- ('Audio', (('vinyl', 'Vinyl'), ('cd', 'CD'))),
- ('Video', (('vhs', 'VHS'), ('dvd', 'DVD'))),
+ ("unknown", "Unknown"),
+ ("Audio", (("vinyl", "Vinyl"), ("cd", "CD"))),
+ ("Video", (("vhs", "VHS"), ("dvd", "DVD"))),
)
html = """
<div>
@@ -95,13 +113,18 @@ class CheckboxSelectMultipleTest(WidgetTest):
</div>
</div>
"""
- self.check_html(self.widget(choices=nested_choices), 'nestchoice', ('vinyl', 'dvd'), html=html)
+ self.check_html(
+ self.widget(choices=nested_choices),
+ "nestchoice",
+ ("vinyl", "dvd"),
+ html=html,
+ )
def test_separate_ids(self):
"""
Each input gets a separate ID.
"""
- choices = [('a', 'A'), ('b', 'B'), ('c', 'C')]
+ choices = [("a", "A"), ("b", "B"), ("c", "C")]
html = """
<div id="abc">
<div>
@@ -113,13 +136,21 @@ class CheckboxSelectMultipleTest(WidgetTest):
</div>
</div>
"""
- self.check_html(self.widget(choices=choices), 'letters', ['a', 'c'], attrs={'id': 'abc'}, html=html)
+ self.check_html(
+ self.widget(choices=choices),
+ "letters",
+ ["a", "c"],
+ attrs={"id": "abc"},
+ html=html,
+ )
def test_separate_ids_constructor(self):
"""
Each input gets a separate ID when the ID is passed to the constructor.
"""
- widget = CheckboxSelectMultiple(attrs={'id': 'abc'}, choices=[('a', 'A'), ('b', 'B'), ('c', 'C')])
+ widget = CheckboxSelectMultiple(
+ attrs={"id": "abc"}, choices=[("a", "A"), ("b", "B"), ("c", "C")]
+ )
html = """
<div id="abc">
<div>
@@ -131,14 +162,14 @@ class CheckboxSelectMultipleTest(WidgetTest):
</div>
</div>
"""
- self.check_html(widget, 'letters', ['a', 'c'], html=html)
+ self.check_html(widget, "letters", ["a", "c"], html=html)
@override_settings(USE_THOUSAND_SEPARATOR=True)
def test_doesnt_localize_input_value(self):
choices = [
- (1, 'One'),
- (1000, 'One thousand'),
- (1000000, 'One million'),
+ (1, "One"),
+ (1000, "One thousand"),
+ (1000000, "One million"),
]
html = """
<div>
@@ -147,11 +178,11 @@ class CheckboxSelectMultipleTest(WidgetTest):
<div><label><input type="checkbox" name="numbers" value="1000000"> One million</label></div>
</div>
"""
- self.check_html(self.widget(choices=choices), 'numbers', None, html=html)
+ self.check_html(self.widget(choices=choices), "numbers", None, html=html)
choices = [
- (datetime.time(0, 0), 'midnight'),
- (datetime.time(12, 0), 'noon'),
+ (datetime.time(0, 0), "midnight"),
+ (datetime.time(12, 0), "noon"),
]
html = """
<div>
@@ -159,7 +190,7 @@ class CheckboxSelectMultipleTest(WidgetTest):
<div><label><input type="checkbox" name="times" value="12:00:00"> noon</label></div>
</div>
"""
- self.check_html(self.widget(choices=choices), 'times', None, html=html)
+ self.check_html(self.widget(choices=choices), "times", None, html=html)
def test_use_required_attribute(self):
widget = self.widget(choices=self.beatles)
@@ -167,22 +198,25 @@ class CheckboxSelectMultipleTest(WidgetTest):
# to be checked instead of at least one.
self.assertIs(widget.use_required_attribute(None), False)
self.assertIs(widget.use_required_attribute([]), False)
- self.assertIs(widget.use_required_attribute(['J', 'P']), False)
+ self.assertIs(widget.use_required_attribute(["J", "P"]), False)
def test_value_omitted_from_data(self):
widget = self.widget(choices=self.beatles)
- self.assertIs(widget.value_omitted_from_data({}, {}, 'field'), False)
- self.assertIs(widget.value_omitted_from_data({'field': 'value'}, {}, 'field'), False)
+ self.assertIs(widget.value_omitted_from_data({}, {}, "field"), False)
+ self.assertIs(
+ widget.value_omitted_from_data({"field": "value"}, {}, "field"), False
+ )
def test_label(self):
"""
CheckboxSelectMultiple doesn't contain 'for="field_0"' in the <label>
because clicking that would toggle the first checkbox.
"""
+
class TestForm(forms.Form):
f = forms.MultipleChoiceField(widget=CheckboxSelectMultiple)
- bound_field = TestForm()['f']
- self.assertEqual(bound_field.field.widget.id_for_label('id'), '')
- self.assertEqual(bound_field.label_tag(), '<label>F:</label>')
- self.assertEqual(bound_field.legend_tag(), '<legend>F:</legend>')
+ bound_field = TestForm()["f"]
+ self.assertEqual(bound_field.field.widget.id_for_label("id"), "")
+ self.assertEqual(bound_field.label_tag(), "<label>F:</label>")
+ self.assertEqual(bound_field.legend_tag(), "<legend>F:</legend>")
diff --git a/tests/forms_tests/widget_tests/test_clearablefileinput.py b/tests/forms_tests/widget_tests/test_clearablefileinput.py
index dee44c4239..03fe34306b 100644
--- a/tests/forms_tests/widget_tests/test_clearablefileinput.py
+++ b/tests/forms_tests/widget_tests/test_clearablefileinput.py
@@ -9,7 +9,8 @@ class FakeFieldFile:
Quacks like a FieldFile (has a .url and string representation), but
doesn't require us to care about storages etc.
"""
- url = 'something'
+
+ url = "something"
def __str__(self):
return self.url
@@ -23,35 +24,46 @@ class ClearableFileInputTest(WidgetTest):
A ClearableFileInput with is_required False and rendered with an
initial value that is a file renders a clear checkbox.
"""
- self.check_html(self.widget, 'myfile', FakeFieldFile(), html=(
- """
+ self.check_html(
+ self.widget,
+ "myfile",
+ FakeFieldFile(),
+ html=(
+ """
Currently: <a href="something">something</a>
<input type="checkbox" name="myfile-clear" id="myfile-clear_id">
<label for="myfile-clear_id">Clear</label><br>
Change: <input type="file" name="myfile">
"""
- ))
+ ),
+ )
def test_html_escaped(self):
"""
A ClearableFileInput should escape name, filename, and URL
when rendering HTML (#15182).
"""
+
class StrangeFieldFile:
url = "something?chapter=1&sect=2&copy=3&lang=en"
def __str__(self):
- return '''something<div onclick="alert('oops')">.jpg'''
+ return """something<div onclick="alert('oops')">.jpg"""
- self.check_html(ClearableFileInput(), 'my<div>file', StrangeFieldFile(), html=(
- """
+ self.check_html(
+ ClearableFileInput(),
+ "my<div>file",
+ StrangeFieldFile(),
+ html=(
+ """
Currently: <a href="something?chapter=1&amp;sect=2&amp;copy=3&amp;lang=en">
something&lt;div onclick=&quot;alert(&#x27;oops&#x27;)&quot;&gt;.jpg</a>
<input type="checkbox" name="my&lt;div&gt;file-clear" id="my&lt;div&gt;file-clear_id">
<label for="my&lt;div&gt;file-clear_id">Clear</label><br>
Change: <input type="file" name="my&lt;div&gt;file">
"""
- ))
+ ),
+ )
def test_clear_input_renders_only_if_not_required(self):
"""
@@ -60,26 +72,33 @@ class ClearableFileInputTest(WidgetTest):
"""
widget = ClearableFileInput()
widget.is_required = True
- self.check_html(widget, 'myfile', FakeFieldFile(), html=(
- """
+ self.check_html(
+ widget,
+ "myfile",
+ FakeFieldFile(),
+ html=(
+ """
Currently: <a href="something">something</a> <br>
Change: <input type="file" name="myfile">
"""
- ))
+ ),
+ )
def test_clear_input_renders_only_if_initial(self):
"""
A ClearableFileInput instantiated with no initial value does not render
a clear checkbox.
"""
- self.check_html(self.widget, 'myfile', None, html='<input type="file" name="myfile">')
+ self.check_html(
+ self.widget, "myfile", None, html='<input type="file" name="myfile">'
+ )
def test_render_disabled(self):
self.check_html(
self.widget,
- 'myfile',
+ "myfile",
FakeFieldFile(),
- attrs={'disabled': True},
+ attrs={"disabled": True},
html=(
'Currently: <a href="something">something</a>'
'<input type="checkbox" name="myfile-clear" '
@@ -92,14 +111,19 @@ class ClearableFileInputTest(WidgetTest):
def test_render_as_subwidget(self):
"""A ClearableFileInput as a subwidget of MultiWidget."""
widget = MultiWidget(widgets=(self.widget,))
- self.check_html(widget, 'myfile', [FakeFieldFile()], html=(
- """
+ self.check_html(
+ widget,
+ "myfile",
+ [FakeFieldFile()],
+ html=(
+ """
Currently: <a href="something">something</a>
<input type="checkbox" name="myfile_0-clear" id="myfile_0-clear_id">
<label for="myfile_0-clear_id">Clear</label><br>
Change: <input type="file" name="myfile_0">
"""
- ))
+ ),
+ )
def test_clear_input_checked_returns_false(self):
"""
@@ -107,9 +131,9 @@ class ClearableFileInputTest(WidgetTest):
checkbox is checked, if not required.
"""
value = self.widget.value_from_datadict(
- data={'myfile-clear': True},
+ data={"myfile-clear": True},
files={},
- name='myfile',
+ name="myfile",
)
self.assertIs(value, False)
@@ -120,12 +144,12 @@ class ClearableFileInputTest(WidgetTest):
"""
widget = ClearableFileInput()
widget.is_required = True
- field = SimpleUploadedFile('something.txt', b'content')
+ field = SimpleUploadedFile("something.txt", b"content")
value = widget.value_from_datadict(
- data={'myfile-clear': True},
- files={'myfile': field},
- name='myfile',
+ data={"myfile-clear": True},
+ files={"myfile": field},
+ name="myfile",
)
self.assertEqual(value, field)
@@ -134,45 +158,50 @@ class ClearableFileInputTest(WidgetTest):
A ClearableFileInput should not mask exceptions produced while
checking that it has a value.
"""
+
class FailingURLFieldFile:
@property
def url(self):
- raise ValueError('Canary')
+ raise ValueError("Canary")
def __str__(self):
- return 'value'
+ return "value"
- with self.assertRaisesMessage(ValueError, 'Canary'):
- self.widget.render('myfile', FailingURLFieldFile())
+ with self.assertRaisesMessage(ValueError, "Canary"):
+ self.widget.render("myfile", FailingURLFieldFile())
def test_url_as_property(self):
class URLFieldFile:
@property
def url(self):
- return 'https://www.python.org/'
+ return "https://www.python.org/"
def __str__(self):
- return 'value'
+ return "value"
- html = self.widget.render('myfile', URLFieldFile())
+ html = self.widget.render("myfile", URLFieldFile())
self.assertInHTML('<a href="https://www.python.org/">value</a>', html)
def test_return_false_if_url_does_not_exists(self):
class NoURLFieldFile:
def __str__(self):
- return 'value'
+ return "value"
- html = self.widget.render('myfile', NoURLFieldFile())
+ html = self.widget.render("myfile", NoURLFieldFile())
self.assertHTMLEqual(html, '<input name="myfile" type="file">')
def test_use_required_attribute(self):
# False when initial data exists. The file input is left blank by the
# user to keep the existing, initial value.
self.assertIs(self.widget.use_required_attribute(None), True)
- self.assertIs(self.widget.use_required_attribute('resume.txt'), False)
+ self.assertIs(self.widget.use_required_attribute("resume.txt"), False)
def test_value_omitted_from_data(self):
widget = ClearableFileInput()
- self.assertIs(widget.value_omitted_from_data({}, {}, 'field'), True)
- self.assertIs(widget.value_omitted_from_data({}, {'field': 'x'}, 'field'), False)
- self.assertIs(widget.value_omitted_from_data({'field-clear': 'y'}, {}, 'field'), False)
+ self.assertIs(widget.value_omitted_from_data({}, {}, "field"), True)
+ self.assertIs(
+ widget.value_omitted_from_data({}, {"field": "x"}, "field"), False
+ )
+ self.assertIs(
+ widget.value_omitted_from_data({"field-clear": "y"}, {}, "field"), False
+ )
diff --git a/tests/forms_tests/widget_tests/test_dateinput.py b/tests/forms_tests/widget_tests/test_dateinput.py
index fa08b345c1..07446480f6 100644
--- a/tests/forms_tests/widget_tests/test_dateinput.py
+++ b/tests/forms_tests/widget_tests/test_dateinput.py
@@ -10,36 +10,53 @@ class DateInputTest(WidgetTest):
widget = DateInput()
def test_render_none(self):
- self.check_html(self.widget, 'date', None, html='<input type="text" name="date">')
+ self.check_html(
+ self.widget, "date", None, html='<input type="text" name="date">'
+ )
def test_render_value(self):
d = date(2007, 9, 17)
- self.assertEqual(str(d), '2007-09-17')
+ self.assertEqual(str(d), "2007-09-17")
- self.check_html(self.widget, 'date', d, html='<input type="text" name="date" value="2007-09-17">')
- self.check_html(self.widget, 'date', date(2007, 9, 17), html=(
- '<input type="text" name="date" value="2007-09-17">'
- ))
+ self.check_html(
+ self.widget,
+ "date",
+ d,
+ html='<input type="text" name="date" value="2007-09-17">',
+ )
+ self.check_html(
+ self.widget,
+ "date",
+ date(2007, 9, 17),
+ html=('<input type="text" name="date" value="2007-09-17">'),
+ )
def test_string(self):
"""
Should be able to initialize from a string value.
"""
- self.check_html(self.widget, 'date', '2007-09-17', html=(
- '<input type="text" name="date" value="2007-09-17">'
- ))
+ self.check_html(
+ self.widget,
+ "date",
+ "2007-09-17",
+ html=('<input type="text" name="date" value="2007-09-17">'),
+ )
def test_format(self):
"""
Use 'format' to change the way a value is displayed.
"""
d = date(2007, 9, 17)
- widget = DateInput(format='%d/%m/%Y', attrs={'type': 'date'})
- self.check_html(widget, 'date', d, html='<input type="date" name="date" value="17/09/2007">')
+ widget = DateInput(format="%d/%m/%Y", attrs={"type": "date"})
+ self.check_html(
+ widget, "date", d, html='<input type="date" name="date" value="17/09/2007">'
+ )
- @translation.override('de-at')
+ @translation.override("de-at")
def test_l10n(self):
self.check_html(
- self.widget, 'date', date(2007, 9, 17),
+ self.widget,
+ "date",
+ date(2007, 9, 17),
html='<input type="text" name="date" value="17.09.2007">',
)
diff --git a/tests/forms_tests/widget_tests/test_datetimeinput.py b/tests/forms_tests/widget_tests/test_datetimeinput.py
index 0a2571f5b7..5795660f30 100644
--- a/tests/forms_tests/widget_tests/test_datetimeinput.py
+++ b/tests/forms_tests/widget_tests/test_datetimeinput.py
@@ -12,42 +12,60 @@ class DateTimeInputTest(WidgetTest):
widget = DateTimeInput()
def test_render_none(self):
- self.check_html(self.widget, 'date', None, '<input type="text" name="date">')
+ self.check_html(self.widget, "date", None, '<input type="text" name="date">')
def test_render_value(self):
"""
The microseconds are trimmed on display, by default.
"""
d = datetime(2007, 9, 17, 12, 51, 34, 482548)
- self.assertEqual(str(d), '2007-09-17 12:51:34.482548')
- self.check_html(self.widget, 'date', d, html=(
- '<input type="text" name="date" value="2007-09-17 12:51:34">'
- ))
- self.check_html(self.widget, 'date', datetime(2007, 9, 17, 12, 51, 34), html=(
- '<input type="text" name="date" value="2007-09-17 12:51:34">'
- ))
- self.check_html(self.widget, 'date', datetime(2007, 9, 17, 12, 51), html=(
- '<input type="text" name="date" value="2007-09-17 12:51:00">'
- ))
+ self.assertEqual(str(d), "2007-09-17 12:51:34.482548")
+ self.check_html(
+ self.widget,
+ "date",
+ d,
+ html=('<input type="text" name="date" value="2007-09-17 12:51:34">'),
+ )
+ self.check_html(
+ self.widget,
+ "date",
+ datetime(2007, 9, 17, 12, 51, 34),
+ html=('<input type="text" name="date" value="2007-09-17 12:51:34">'),
+ )
+ self.check_html(
+ self.widget,
+ "date",
+ datetime(2007, 9, 17, 12, 51),
+ html=('<input type="text" name="date" value="2007-09-17 12:51:00">'),
+ )
def test_render_formatted(self):
"""
Use 'format' to change the way a value is displayed.
"""
widget = DateTimeInput(
- format='%d/%m/%Y %H:%M', attrs={'type': 'datetime'},
+ format="%d/%m/%Y %H:%M",
+ attrs={"type": "datetime"},
)
d = datetime(2007, 9, 17, 12, 51, 34, 482548)
- self.check_html(widget, 'date', d, html='<input type="datetime" name="date" value="17/09/2007 12:51">')
+ self.check_html(
+ widget,
+ "date",
+ d,
+ html='<input type="datetime" name="date" value="17/09/2007 12:51">',
+ )
- @translation.override('de-at')
+ @translation.override("de-at")
def test_l10n(self):
d = datetime(2007, 9, 17, 12, 51, 34, 482548)
- self.check_html(self.widget, 'date', d, html=(
- '<input type="text" name="date" value="17.09.2007 12:51:34">'
- ))
+ self.check_html(
+ self.widget,
+ "date",
+ d,
+ html=('<input type="text" name="date" value="17.09.2007 12:51:34">'),
+ )
- @translation.override('de-at')
+ @translation.override("de-at")
def test_locale_aware(self):
d = datetime(2007, 9, 17, 12, 51, 34, 482548)
# RemovedInDjango50Warning: When the deprecation ends, remove
@@ -56,15 +74,23 @@ class DateTimeInputTest(WidgetTest):
# locale-dictated formats.
with ignore_warnings(category=RemovedInDjango50Warning):
with self.settings(USE_L10N=False):
- with self.settings(DATETIME_INPUT_FORMATS=[
- '%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M:%S.%f', '%Y-%m-%d %H:%M',
- ]):
+ with self.settings(
+ DATETIME_INPUT_FORMATS=[
+ "%Y-%m-%d %H:%M:%S",
+ "%Y-%m-%d %H:%M:%S.%f",
+ "%Y-%m-%d %H:%M",
+ ]
+ ):
self.check_html(
- self.widget, 'date', d,
+ self.widget,
+ "date",
+ d,
html='<input type="text" name="date" value="2007-09-17 12:51:34">',
)
- with translation.override('es'):
+ with translation.override("es"):
self.check_html(
- self.widget, 'date', d,
+ self.widget,
+ "date",
+ d,
html='<input type="text" name="date" value="17/09/2007 12:51:34">',
)
diff --git a/tests/forms_tests/widget_tests/test_fileinput.py b/tests/forms_tests/widget_tests/test_fileinput.py
index 8eec26253a..ea11c639e4 100644
--- a/tests/forms_tests/widget_tests/test_fileinput.py
+++ b/tests/forms_tests/widget_tests/test_fileinput.py
@@ -11,16 +11,27 @@ class FileInputTest(WidgetTest):
FileInput widgets never render the value attribute. The old value
isn't useful if a form is updated or an error occurred.
"""
- self.check_html(self.widget, 'email', 'test@example.com', html='<input type="file" name="email">')
- self.check_html(self.widget, 'email', '', html='<input type="file" name="email">')
- self.check_html(self.widget, 'email', None, html='<input type="file" name="email">')
+ self.check_html(
+ self.widget,
+ "email",
+ "test@example.com",
+ html='<input type="file" name="email">',
+ )
+ self.check_html(
+ self.widget, "email", "", html='<input type="file" name="email">'
+ )
+ self.check_html(
+ self.widget, "email", None, html='<input type="file" name="email">'
+ )
def test_value_omitted_from_data(self):
- self.assertIs(self.widget.value_omitted_from_data({}, {}, 'field'), True)
- self.assertIs(self.widget.value_omitted_from_data({}, {'field': 'value'}, 'field'), False)
+ self.assertIs(self.widget.value_omitted_from_data({}, {}, "field"), True)
+ self.assertIs(
+ self.widget.value_omitted_from_data({}, {"field": "value"}, "field"), False
+ )
def test_use_required_attribute(self):
# False when initial data exists. The file input is left blank by the
# user to keep the existing, initial value.
self.assertIs(self.widget.use_required_attribute(None), True)
- self.assertIs(self.widget.use_required_attribute('resume.txt'), False)
+ self.assertIs(self.widget.use_required_attribute("resume.txt"), False)
diff --git a/tests/forms_tests/widget_tests/test_hiddeninput.py b/tests/forms_tests/widget_tests/test_hiddeninput.py
index a7d036410c..ba5e796501 100644
--- a/tests/forms_tests/widget_tests/test_hiddeninput.py
+++ b/tests/forms_tests/widget_tests/test_hiddeninput.py
@@ -7,11 +7,13 @@ class HiddenInputTest(WidgetTest):
widget = HiddenInput()
def test_render(self):
- self.check_html(self.widget, 'email', '', html='<input type="hidden" name="email">')
+ self.check_html(
+ self.widget, "email", "", html='<input type="hidden" name="email">'
+ )
def test_use_required_attribute(self):
# Always False to avoid browser validation on inputs hidden from the
# user.
self.assertIs(self.widget.use_required_attribute(None), False)
- self.assertIs(self.widget.use_required_attribute(''), False)
- self.assertIs(self.widget.use_required_attribute('foo'), False)
+ self.assertIs(self.widget.use_required_attribute(""), False)
+ self.assertIs(self.widget.use_required_attribute("foo"), False)
diff --git a/tests/forms_tests/widget_tests/test_input.py b/tests/forms_tests/widget_tests/test_input.py
index 8be971826e..72c2c217c0 100644
--- a/tests/forms_tests/widget_tests/test_input.py
+++ b/tests/forms_tests/widget_tests/test_input.py
@@ -4,12 +4,20 @@ from .base import WidgetTest
class InputTests(WidgetTest):
-
def test_attrs_with_type(self):
- attrs = {'type': 'date'}
+ attrs = {"type": "date"}
widget = Input(attrs)
- self.check_html(widget, 'name', 'value', '<input type="date" name="name" value="value">')
+ self.check_html(
+ widget, "name", "value", '<input type="date" name="name" value="value">'
+ )
# reuse the same attrs for another widget
- self.check_html(Input(attrs), 'name', 'value', '<input type="date" name="name" value="value">')
- attrs['type'] = 'number' # shouldn't change the widget type
- self.check_html(widget, 'name', 'value', '<input type="date" name="name" value="value">')
+ self.check_html(
+ Input(attrs),
+ "name",
+ "value",
+ '<input type="date" name="name" value="value">',
+ )
+ attrs["type"] = "number" # shouldn't change the widget type
+ self.check_html(
+ widget, "name", "value", '<input type="date" name="name" value="value">'
+ )
diff --git a/tests/forms_tests/widget_tests/test_multiplehiddeninput.py b/tests/forms_tests/widget_tests/test_multiplehiddeninput.py
index 37d54174ee..d0ad188929 100644
--- a/tests/forms_tests/widget_tests/test_multiplehiddeninput.py
+++ b/tests/forms_tests/widget_tests/test_multiplehiddeninput.py
@@ -8,13 +8,17 @@ class MultipleHiddenInputTest(WidgetTest):
def test_render_single(self):
self.check_html(
- self.widget, 'email', ['test@example.com'],
+ self.widget,
+ "email",
+ ["test@example.com"],
html='<input type="hidden" name="email" value="test@example.com">',
)
def test_render_multiple(self):
self.check_html(
- self.widget, 'email', ['test@example.com', 'foo@example.com'],
+ self.widget,
+ "email",
+ ["test@example.com", "foo@example.com"],
html=(
'<input type="hidden" name="email" value="test@example.com">\n'
'<input type="hidden" name="email" value="foo@example.com">'
@@ -23,13 +27,19 @@ class MultipleHiddenInputTest(WidgetTest):
def test_render_attrs(self):
self.check_html(
- self.widget, 'email', ['test@example.com'], attrs={'class': 'fun'},
+ self.widget,
+ "email",
+ ["test@example.com"],
+ attrs={"class": "fun"},
html='<input type="hidden" name="email" value="test@example.com" class="fun">',
)
def test_render_attrs_multiple(self):
self.check_html(
- self.widget, 'email', ['test@example.com', 'foo@example.com'], attrs={'class': 'fun'},
+ self.widget,
+ "email",
+ ["test@example.com", "foo@example.com"],
+ attrs={"class": "fun"},
html=(
'<input type="hidden" name="email" value="test@example.com" class="fun">\n'
'<input type="hidden" name="email" value="foo@example.com" class="fun">'
@@ -37,36 +47,46 @@ class MultipleHiddenInputTest(WidgetTest):
)
def test_render_attrs_constructor(self):
- widget = MultipleHiddenInput(attrs={'class': 'fun'})
- self.check_html(widget, 'email', [], '')
+ widget = MultipleHiddenInput(attrs={"class": "fun"})
+ self.check_html(widget, "email", [], "")
self.check_html(
- widget, 'email', ['foo@example.com'],
+ widget,
+ "email",
+ ["foo@example.com"],
html='<input type="hidden" class="fun" value="foo@example.com" name="email">',
)
self.check_html(
- widget, 'email', ['foo@example.com', 'test@example.com'],
+ widget,
+ "email",
+ ["foo@example.com", "test@example.com"],
html=(
'<input type="hidden" class="fun" value="foo@example.com" name="email">\n'
'<input type="hidden" class="fun" value="test@example.com" name="email">'
),
)
self.check_html(
- widget, 'email', ['foo@example.com'], attrs={'class': 'special'},
+ widget,
+ "email",
+ ["foo@example.com"],
+ attrs={"class": "special"},
html='<input type="hidden" class="special" value="foo@example.com" name="email">',
)
def test_render_empty(self):
- self.check_html(self.widget, 'email', [], '')
+ self.check_html(self.widget, "email", [], "")
def test_render_none(self):
- self.check_html(self.widget, 'email', None, '')
+ self.check_html(self.widget, "email", None, "")
def test_render_increment_id(self):
"""
Each input should get a separate ID.
"""
self.check_html(
- self.widget, 'letters', ['a', 'b', 'c'], attrs={'id': 'hideme'},
+ self.widget,
+ "letters",
+ ["a", "b", "c"],
+ attrs={"id": "hideme"},
html=(
'<input type="hidden" name="letters" value="a" id="hideme_0">\n'
'<input type="hidden" name="letters" value="b" id="hideme_1">\n'
diff --git a/tests/forms_tests/widget_tests/test_multiwidget.py b/tests/forms_tests/widget_tests/test_multiwidget.py
index cb1e9d31c5..c3f676e3f7 100644
--- a/tests/forms_tests/widget_tests/test_multiwidget.py
+++ b/tests/forms_tests/widget_tests/test_multiwidget.py
@@ -2,8 +2,15 @@ import copy
from datetime import datetime
from django.forms import (
- CharField, FileInput, MultipleChoiceField, MultiValueField, MultiWidget,
- RadioSelect, SelectMultiple, SplitDateTimeField, SplitDateTimeWidget,
+ CharField,
+ FileInput,
+ MultipleChoiceField,
+ MultiValueField,
+ MultiWidget,
+ RadioSelect,
+ SelectMultiple,
+ SplitDateTimeField,
+ SplitDateTimeWidget,
TextInput,
)
@@ -13,8 +20,8 @@ from .base import WidgetTest
class MyMultiWidget(MultiWidget):
def decompress(self, value):
if value:
- return value.split('__')
- return ['', '']
+ return value.split("__")
+ return ["", ""]
class ComplexMultiWidget(MultiWidget):
@@ -28,9 +35,11 @@ class ComplexMultiWidget(MultiWidget):
def decompress(self, value):
if value:
- data = value.split(',')
+ data = value.split(",")
return [
- data[0], list(data[1]), datetime.strptime(data[2], "%Y-%m-%d %H:%M:%S")
+ data[0],
+ list(data[1]),
+ datetime.strptime(data[2], "%Y-%m-%d %H:%M:%S"),
]
return [None, None, None]
@@ -46,8 +55,10 @@ class ComplexField(MultiValueField):
def compress(self, data_list):
if data_list:
- return '%s,%s,%s' % (
- data_list[0], ''.join(data_list[1]), data_list[2],
+ return "%s,%s,%s" % (
+ data_list[0],
+ "".join(data_list[1]),
+ data_list[2],
)
return None
@@ -56,6 +67,7 @@ class DeepCopyWidget(MultiWidget):
"""
Used to test MultiWidget.__deepcopy__().
"""
+
def __init__(self, choices=[]):
widgets = [
RadioSelect(choices=choices),
@@ -75,6 +87,7 @@ class DeepCopyWidget(MultiWidget):
The choices for this widget are the Select widget's choices.
"""
return self.widgets[0].choices
+
choices = property(_get_choices, _set_choices)
@@ -82,97 +95,144 @@ class MultiWidgetTest(WidgetTest):
def test_subwidgets_name(self):
widget = MultiWidget(
widgets={
- '': TextInput(),
- 'big': TextInput(attrs={'class': 'big'}),
- 'small': TextInput(attrs={'class': 'small'}),
+ "": TextInput(),
+ "big": TextInput(attrs={"class": "big"}),
+ "small": TextInput(attrs={"class": "small"}),
},
)
- self.check_html(widget, 'name', ['John', 'George', 'Paul'], html=(
- '<input type="text" name="name" value="John">'
- '<input type="text" name="name_big" value="George" class="big">'
- '<input type="text" name="name_small" value="Paul" class="small">'
- ))
+ self.check_html(
+ widget,
+ "name",
+ ["John", "George", "Paul"],
+ html=(
+ '<input type="text" name="name" value="John">'
+ '<input type="text" name="name_big" value="George" class="big">'
+ '<input type="text" name="name_small" value="Paul" class="small">'
+ ),
+ )
def test_text_inputs(self):
widget = MyMultiWidget(
widgets=(
- TextInput(attrs={'class': 'big'}),
- TextInput(attrs={'class': 'small'}),
+ TextInput(attrs={"class": "big"}),
+ TextInput(attrs={"class": "small"}),
)
)
- self.check_html(widget, 'name', ['john', 'lennon'], html=(
- '<input type="text" class="big" value="john" name="name_0">'
- '<input type="text" class="small" value="lennon" name="name_1">'
- ))
- self.check_html(widget, 'name', 'john__lennon', html=(
- '<input type="text" class="big" value="john" name="name_0">'
- '<input type="text" class="small" value="lennon" name="name_1">'
- ))
- self.check_html(widget, 'name', 'john__lennon', attrs={'id': 'foo'}, html=(
- '<input id="foo_0" type="text" class="big" value="john" name="name_0">'
- '<input id="foo_1" type="text" class="small" value="lennon" name="name_1">'
- ))
+ self.check_html(
+ widget,
+ "name",
+ ["john", "lennon"],
+ html=(
+ '<input type="text" class="big" value="john" name="name_0">'
+ '<input type="text" class="small" value="lennon" name="name_1">'
+ ),
+ )
+ self.check_html(
+ widget,
+ "name",
+ "john__lennon",
+ html=(
+ '<input type="text" class="big" value="john" name="name_0">'
+ '<input type="text" class="small" value="lennon" name="name_1">'
+ ),
+ )
+ self.check_html(
+ widget,
+ "name",
+ "john__lennon",
+ attrs={"id": "foo"},
+ html=(
+ '<input id="foo_0" type="text" class="big" value="john" name="name_0">'
+ '<input id="foo_1" type="text" class="small" value="lennon" name="name_1">'
+ ),
+ )
def test_constructor_attrs(self):
widget = MyMultiWidget(
widgets=(
- TextInput(attrs={'class': 'big'}),
- TextInput(attrs={'class': 'small'}),
+ TextInput(attrs={"class": "big"}),
+ TextInput(attrs={"class": "small"}),
+ ),
+ attrs={"id": "bar"},
+ )
+ self.check_html(
+ widget,
+ "name",
+ ["john", "lennon"],
+ html=(
+ '<input id="bar_0" type="text" class="big" value="john" name="name_0">'
+ '<input id="bar_1" type="text" class="small" value="lennon" name="name_1">'
),
- attrs={'id': 'bar'},
)
- self.check_html(widget, 'name', ['john', 'lennon'], html=(
- '<input id="bar_0" type="text" class="big" value="john" name="name_0">'
- '<input id="bar_1" type="text" class="small" value="lennon" name="name_1">'
- ))
def test_constructor_attrs_with_type(self):
- attrs = {'type': 'number'}
+ attrs = {"type": "number"}
widget = MyMultiWidget(widgets=(TextInput, TextInput()), attrs=attrs)
- self.check_html(widget, 'code', ['1', '2'], html=(
- '<input type="number" value="1" name="code_0">'
- '<input type="number" value="2" name="code_1">'
- ))
- widget = MyMultiWidget(widgets=(TextInput(attrs), TextInput(attrs)), attrs={'class': 'bar'})
- self.check_html(widget, 'code', ['1', '2'], html=(
- '<input type="number" value="1" name="code_0" class="bar">'
- '<input type="number" value="2" name="code_1" class="bar">'
- ))
+ self.check_html(
+ widget,
+ "code",
+ ["1", "2"],
+ html=(
+ '<input type="number" value="1" name="code_0">'
+ '<input type="number" value="2" name="code_1">'
+ ),
+ )
+ widget = MyMultiWidget(
+ widgets=(TextInput(attrs), TextInput(attrs)), attrs={"class": "bar"}
+ )
+ self.check_html(
+ widget,
+ "code",
+ ["1", "2"],
+ html=(
+ '<input type="number" value="1" name="code_0" class="bar">'
+ '<input type="number" value="2" name="code_1" class="bar">'
+ ),
+ )
def test_value_omitted_from_data(self):
widget = MyMultiWidget(widgets=(TextInput(), TextInput()))
- self.assertIs(widget.value_omitted_from_data({}, {}, 'field'), True)
- self.assertIs(widget.value_omitted_from_data({'field_0': 'x'}, {}, 'field'), False)
- self.assertIs(widget.value_omitted_from_data({'field_1': 'y'}, {}, 'field'), False)
- self.assertIs(widget.value_omitted_from_data({'field_0': 'x', 'field_1': 'y'}, {}, 'field'), False)
+ self.assertIs(widget.value_omitted_from_data({}, {}, "field"), True)
+ self.assertIs(
+ widget.value_omitted_from_data({"field_0": "x"}, {}, "field"), False
+ )
+ self.assertIs(
+ widget.value_omitted_from_data({"field_1": "y"}, {}, "field"), False
+ )
+ self.assertIs(
+ widget.value_omitted_from_data(
+ {"field_0": "x", "field_1": "y"}, {}, "field"
+ ),
+ False,
+ )
def test_value_from_datadict_subwidgets_name(self):
- widget = MultiWidget(widgets={'x': TextInput(), '': TextInput()})
+ widget = MultiWidget(widgets={"x": TextInput(), "": TextInput()})
tests = [
({}, [None, None]),
- ({'field': 'x'}, [None, 'x']),
- ({'field_x': 'y'}, ['y', None]),
- ({'field': 'x', 'field_x': 'y'}, ['y', 'x']),
+ ({"field": "x"}, [None, "x"]),
+ ({"field_x": "y"}, ["y", None]),
+ ({"field": "x", "field_x": "y"}, ["y", "x"]),
]
for data, expected in tests:
with self.subTest(data):
self.assertEqual(
- widget.value_from_datadict(data, {}, 'field'),
+ widget.value_from_datadict(data, {}, "field"),
expected,
)
def test_value_omitted_from_data_subwidgets_name(self):
- widget = MultiWidget(widgets={'x': TextInput(), '': TextInput()})
+ widget = MultiWidget(widgets={"x": TextInput(), "": TextInput()})
tests = [
({}, True),
- ({'field': 'x'}, False),
- ({'field_x': 'y'}, False),
- ({'field': 'x', 'field_x': 'y'}, False),
+ ({"field": "x"}, False),
+ ({"field_x": "y"}, False),
+ ({"field": "x", "field_x": "y"}, False),
]
for data, expected in tests:
with self.subTest(data):
self.assertIs(
- widget.value_omitted_from_data(data, {}, 'field'),
+ widget.value_omitted_from_data(data, {}, "field"),
expected,
)
@@ -195,8 +255,12 @@ class MultiWidgetTest(WidgetTest):
MultiWidgets can be composed of other MultiWidgets.
"""
widget = ComplexMultiWidget()
- self.check_html(widget, 'name', 'some text,JP,2007-04-25 06:24:00', html=(
- """
+ self.check_html(
+ widget,
+ "name",
+ "some text,JP,2007-04-25 06:24:00",
+ html=(
+ """
<input type="text" name="name_0" value="some text">
<select multiple name="name_1">
<option value="J" selected>John</option>
@@ -207,13 +271,18 @@ class MultiWidgetTest(WidgetTest):
<input type="text" name="name_2_0" value="2007-04-25">
<input type="text" name="name_2_1" value="06:24:00">
"""
- ))
+ ),
+ )
def test_no_whitespace_between_widgets(self):
widget = MyMultiWidget(widgets=(TextInput, TextInput()))
- self.check_html(widget, 'code', None, html=(
- '<input type="text" name="code_0"><input type="text" name="code_1">'
- ), strict=True)
+ self.check_html(
+ widget,
+ "code",
+ None,
+ html=('<input type="text" name="code_0"><input type="text" name="code_1">'),
+ strict=True,
+ )
def test_deepcopy(self):
"""
diff --git a/tests/forms_tests/widget_tests/test_nullbooleanselect.py b/tests/forms_tests/widget_tests/test_nullbooleanselect.py
index 4e34020cdd..927abdba01 100644
--- a/tests/forms_tests/widget_tests/test_nullbooleanselect.py
+++ b/tests/forms_tests/widget_tests/test_nullbooleanselect.py
@@ -8,85 +8,130 @@ class NullBooleanSelectTest(WidgetTest):
widget = NullBooleanSelect()
def test_render_true(self):
- self.check_html(self.widget, 'is_cool', True, html=(
- """<select name="is_cool">
+ self.check_html(
+ self.widget,
+ "is_cool",
+ True,
+ html=(
+ """<select name="is_cool">
<option value="unknown">Unknown</option>
<option value="true" selected>Yes</option>
<option value="false">No</option>
</select>"""
- ))
+ ),
+ )
def test_render_false(self):
- self.check_html(self.widget, 'is_cool', False, html=(
- """<select name="is_cool">
+ self.check_html(
+ self.widget,
+ "is_cool",
+ False,
+ html=(
+ """<select name="is_cool">
<option value="unknown">Unknown</option>
<option value="true">Yes</option>
<option value="false" selected>No</option>
</select>"""
- ))
+ ),
+ )
def test_render_none(self):
- self.check_html(self.widget, 'is_cool', None, html=(
- """<select name="is_cool">
+ self.check_html(
+ self.widget,
+ "is_cool",
+ None,
+ html=(
+ """<select name="is_cool">
<option value="unknown" selected>Unknown</option>
<option value="true">Yes</option>
<option value="false">No</option>
</select>"""
- ))
+ ),
+ )
def test_render_value_unknown(self):
- self.check_html(self.widget, 'is_cool', 'unknown', html=(
- """<select name="is_cool">
+ self.check_html(
+ self.widget,
+ "is_cool",
+ "unknown",
+ html=(
+ """<select name="is_cool">
<option value="unknown" selected>Unknown</option>
<option value="true">Yes</option>
<option value="false">No</option>
</select>"""
- ))
+ ),
+ )
def test_render_value_true(self):
- self.check_html(self.widget, 'is_cool', 'true', html=(
- """<select name="is_cool">
+ self.check_html(
+ self.widget,
+ "is_cool",
+ "true",
+ html=(
+ """<select name="is_cool">
<option value="unknown">Unknown</option>
<option value="true" selected>Yes</option>
<option value="false">No</option>
</select>"""
- ))
+ ),
+ )
def test_render_value_false(self):
- self.check_html(self.widget, 'is_cool', 'false', html=(
- """<select name="is_cool">
+ self.check_html(
+ self.widget,
+ "is_cool",
+ "false",
+ html=(
+ """<select name="is_cool">
<option value="unknown">Unknown</option>
<option value="true">Yes</option>
<option value="false" selected>No</option>
</select>"""
- ))
+ ),
+ )
def test_render_value_1(self):
- self.check_html(self.widget, 'is_cool', '1', html=(
- """<select name="is_cool">
+ self.check_html(
+ self.widget,
+ "is_cool",
+ "1",
+ html=(
+ """<select name="is_cool">
<option value="unknown" selected>Unknown</option>
<option value="true">Yes</option>
<option value="false">No</option>
</select>"""
- ))
+ ),
+ )
def test_render_value_2(self):
- self.check_html(self.widget, 'is_cool', '2', html=(
- """<select name="is_cool">
+ self.check_html(
+ self.widget,
+ "is_cool",
+ "2",
+ html=(
+ """<select name="is_cool">
<option value="unknown">Unknown</option>
<option value="true" selected>Yes</option>
<option value="false">No</option>
</select>"""
- ))
+ ),
+ )
def test_render_value_3(self):
- self.check_html(self.widget, 'is_cool', '3', html=(
- """<select name="is_cool">
+ self.check_html(
+ self.widget,
+ "is_cool",
+ "3",
+ html=(
+ """<select name="is_cool">
<option value="unknown">Unknown</option>
<option value="true">Yes</option>
<option value="false" selected>No</option>
</select>"""
- ))
+ ),
+ )
def test_l10n(self):
"""
@@ -94,13 +139,18 @@ class NullBooleanSelectTest(WidgetTest):
"""
widget = NullBooleanSelect()
- with translation.override('de-at'):
- self.check_html(widget, 'id_bool', True, html=(
- """
+ with translation.override("de-at"):
+ self.check_html(
+ widget,
+ "id_bool",
+ True,
+ html=(
+ """
<select name="id_bool">
<option value="unknown">Unbekannt</option>
<option value="true" selected>Ja</option>
<option value="false">Nein</option>
</select>
"""
- ))
+ ),
+ )
diff --git a/tests/forms_tests/widget_tests/test_numberinput.py b/tests/forms_tests/widget_tests/test_numberinput.py
index 9fda30e156..a6427e6e37 100644
--- a/tests/forms_tests/widget_tests/test_numberinput.py
+++ b/tests/forms_tests/widget_tests/test_numberinput.py
@@ -5,11 +5,12 @@ from .base import WidgetTest
class NumberInputTests(WidgetTest):
-
@override_settings(USE_THOUSAND_SEPARATOR=True)
def test_attrs_not_localized(self):
- widget = NumberInput(attrs={'max': 12345, 'min': 1234, 'step': 9999})
+ widget = NumberInput(attrs={"max": 12345, "min": 1234, "step": 9999})
self.check_html(
- widget, 'name', 'value',
- '<input type="number" name="name" value="value" max="12345" min="1234" step="9999">'
+ widget,
+ "name",
+ "value",
+ '<input type="number" name="name" value="value" max="12345" min="1234" step="9999">',
)
diff --git a/tests/forms_tests/widget_tests/test_passwordinput.py b/tests/forms_tests/widget_tests/test_passwordinput.py
index ecbe274d69..1adf0cc3cb 100644
--- a/tests/forms_tests/widget_tests/test_passwordinput.py
+++ b/tests/forms_tests/widget_tests/test_passwordinput.py
@@ -7,10 +7,17 @@ class PasswordInputTest(WidgetTest):
widget = PasswordInput()
def test_render(self):
- self.check_html(self.widget, 'password', '', html='<input type="password" name="password">')
+ self.check_html(
+ self.widget, "password", "", html='<input type="password" name="password">'
+ )
def test_render_ignore_value(self):
- self.check_html(self.widget, 'password', 'secret', html='<input type="password" name="password">')
+ self.check_html(
+ self.widget,
+ "password",
+ "secret",
+ html='<input type="password" name="password">',
+ )
def test_render_value_true(self):
"""
@@ -18,9 +25,15 @@ class PasswordInputTest(WidgetTest):
render its value. For security reasons, this is off by default.
"""
widget = PasswordInput(render_value=True)
- self.check_html(widget, 'password', '', html='<input type="password" name="password">')
- self.check_html(widget, 'password', None, html='<input type="password" name="password">')
self.check_html(
- widget, 'password', 'test@example.com',
+ widget, "password", "", html='<input type="password" name="password">'
+ )
+ self.check_html(
+ widget, "password", None, html='<input type="password" name="password">'
+ )
+ self.check_html(
+ widget,
+ "password",
+ "test@example.com",
html='<input type="password" name="password" value="test@example.com">',
)
diff --git a/tests/forms_tests/widget_tests/test_radioselect.py b/tests/forms_tests/widget_tests/test_radioselect.py
index 9622517144..89e4022f1c 100644
--- a/tests/forms_tests/widget_tests/test_radioselect.py
+++ b/tests/forms_tests/widget_tests/test_radioselect.py
@@ -10,8 +10,12 @@ class RadioSelectTest(WidgetTest):
widget = RadioSelect
def test_render(self):
- choices = (('', '------'),) + self.beatles
- self.check_html(self.widget(choices=choices), 'beatle', 'J', html="""
+ choices = (("", "------"),) + self.beatles
+ self.check_html(
+ self.widget(choices=choices),
+ "beatle",
+ "J",
+ html="""
<div>
<div><label><input type="radio" name="beatle" value=""> ------</label></div>
<div><label><input checked type="radio" name="beatle" value="J"> John</label></div>
@@ -19,13 +23,14 @@ class RadioSelectTest(WidgetTest):
<div><label><input type="radio" name="beatle" value="G"> George</label></div>
<div><label><input type="radio" name="beatle" value="R"> Ringo</label></div>
</div>
- """)
+ """,
+ )
def test_nested_choices(self):
nested_choices = (
- ('unknown', 'Unknown'),
- ('Audio', (('vinyl', 'Vinyl'), ('cd', 'CD'))),
- ('Video', (('vhs', 'VHS'), ('dvd', 'DVD'))),
+ ("unknown", "Unknown"),
+ ("Audio", (("vinyl", "Vinyl"), ("cd", "CD"))),
+ ("Video", (("vhs", "VHS"), ("dvd", "DVD"))),
)
html = """
<div id="media">
@@ -47,8 +52,11 @@ class RadioSelectTest(WidgetTest):
</div>
"""
self.check_html(
- self.widget(choices=nested_choices), 'nestchoice', 'dvd',
- attrs={'id': 'media'}, html=html,
+ self.widget(choices=nested_choices),
+ "nestchoice",
+ "dvd",
+ attrs={"id": "media"},
+ html=html,
)
def test_constructor_attrs(self):
@@ -56,7 +64,7 @@ class RadioSelectTest(WidgetTest):
Attributes provided at instantiation are passed to the constituent
inputs.
"""
- widget = RadioSelect(attrs={'id': 'foo'}, choices=self.beatles)
+ widget = RadioSelect(attrs={"id": "foo"}, choices=self.beatles)
html = """
<div id="foo">
<div>
@@ -67,7 +75,7 @@ class RadioSelectTest(WidgetTest):
<div><label for="foo_3"><input type="radio" id="foo_3" value="R" name="beatle"> Ringo</label></div>
</div>
"""
- self.check_html(widget, 'beatle', 'J', html=html)
+ self.check_html(widget, "beatle", "J", html=html)
def test_render_attrs(self):
"""
@@ -84,7 +92,13 @@ class RadioSelectTest(WidgetTest):
<div><label for="bar_3"><input type="radio" id="bar_3" value="R" name="beatle"> Ringo</label></div>
</div>
"""
- self.check_html(self.widget(choices=self.beatles), 'beatle', 'J', attrs={'id': 'bar'}, html=html)
+ self.check_html(
+ self.widget(choices=self.beatles),
+ "beatle",
+ "J",
+ attrs={"id": "bar"},
+ html=html,
+ )
def test_class_attrs(self):
"""
@@ -99,14 +113,20 @@ class RadioSelectTest(WidgetTest):
<div><label><input type="radio" class="bar" value="R" name="beatle"> Ringo</label></div>
</div>
"""
- self.check_html(self.widget(choices=self.beatles), 'beatle', 'J', attrs={'class': 'bar'}, html=html)
+ self.check_html(
+ self.widget(choices=self.beatles),
+ "beatle",
+ "J",
+ attrs={"class": "bar"},
+ html=html,
+ )
@override_settings(USE_THOUSAND_SEPARATOR=True)
def test_doesnt_localize_input_value(self):
choices = [
- (1, 'One'),
- (1000, 'One thousand'),
- (1000000, 'One million'),
+ (1, "One"),
+ (1000, "One thousand"),
+ (1000000, "One million"),
]
html = """
<div>
@@ -115,11 +135,11 @@ class RadioSelectTest(WidgetTest):
<div><label><input type="radio" name="number" value="1000000"> One million</label></div>
</div>
"""
- self.check_html(self.widget(choices=choices), 'number', None, html=html)
+ self.check_html(self.widget(choices=choices), "number", None, html=html)
choices = [
- (datetime.time(0, 0), 'midnight'),
- (datetime.time(12, 0), 'noon'),
+ (datetime.time(0, 0), "midnight"),
+ (datetime.time(12, 0), "noon"),
]
html = """
<div>
@@ -127,12 +147,16 @@ class RadioSelectTest(WidgetTest):
<div><label><input type="radio" name="time" value="12:00:00"> noon</label></div>
</div>
"""
- self.check_html(self.widget(choices=choices), 'time', None, html=html)
+ self.check_html(self.widget(choices=choices), "time", None, html=html)
def test_render_as_subwidget(self):
"""A RadioSelect as a subwidget of MultiWidget."""
- choices = (('', '------'),) + self.beatles
- self.check_html(MultiWidget([self.widget(choices=choices)]), 'beatle', ['J'], html="""
+ choices = (("", "------"),) + self.beatles
+ self.check_html(
+ MultiWidget([self.widget(choices=choices)]),
+ "beatle",
+ ["J"],
+ html="""
<div>
<div><label><input type="radio" name="beatle_0" value=""> ------</label></div>
<div><label><input checked type="radio" name="beatle_0" value="J"> John</label></div>
@@ -140,4 +164,5 @@ class RadioSelectTest(WidgetTest):
<div><label><input type="radio" name="beatle_0" value="G"> George</label></div>
<div><label><input type="radio" name="beatle_0" value="R"> Ringo</label></div>
</div>
- """)
+ """,
+ )
diff --git a/tests/forms_tests/widget_tests/test_select.py b/tests/forms_tests/widget_tests/test_select.py
index dc2030e3ae..e78feeb110 100644
--- a/tests/forms_tests/widget_tests/test_select.py
+++ b/tests/forms_tests/widget_tests/test_select.py
@@ -10,87 +10,115 @@ from .base import WidgetTest
class SelectTest(WidgetTest):
widget = Select
- nested_widget = Select(choices=(
- ('outer1', 'Outer 1'),
- ('Group "1"', (('inner1', 'Inner 1'), ('inner2', 'Inner 2'))),
- ))
+ nested_widget = Select(
+ choices=(
+ ("outer1", "Outer 1"),
+ ('Group "1"', (("inner1", "Inner 1"), ("inner2", "Inner 2"))),
+ )
+ )
def test_render(self):
- self.check_html(self.widget(choices=self.beatles), 'beatle', 'J', html=(
- """<select name="beatle">
+ self.check_html(
+ self.widget(choices=self.beatles),
+ "beatle",
+ "J",
+ html=(
+ """<select name="beatle">
<option value="J" selected>John</option>
<option value="P">Paul</option>
<option value="G">George</option>
<option value="R">Ringo</option>
</select>"""
- ))
+ ),
+ )
def test_render_none(self):
"""
If the value is None, none of the options are selected.
"""
- self.check_html(self.widget(choices=self.beatles), 'beatle', None, html=(
- """<select name="beatle">
+ self.check_html(
+ self.widget(choices=self.beatles),
+ "beatle",
+ None,
+ html=(
+ """<select name="beatle">
<option value="J">John</option>
<option value="P">Paul</option>
<option value="G">George</option>
<option value="R">Ringo</option>
</select>"""
- ))
+ ),
+ )
def test_render_label_value(self):
"""
If the value corresponds to a label (but not to an option value), none
of the options are selected.
"""
- self.check_html(self.widget(choices=self.beatles), 'beatle', 'John', html=(
- """<select name="beatle">
+ self.check_html(
+ self.widget(choices=self.beatles),
+ "beatle",
+ "John",
+ html=(
+ """<select name="beatle">
<option value="J">John</option>
<option value="P">Paul</option>
<option value="G">George</option>
<option value="R">Ringo</option>
</select>"""
- ))
+ ),
+ )
def test_render_selected(self):
"""
Only one option can be selected (#8103).
"""
- choices = [('0', '0'), ('1', '1'), ('2', '2'), ('3', '3'), ('0', 'extra')]
+ choices = [("0", "0"), ("1", "1"), ("2", "2"), ("3", "3"), ("0", "extra")]
- self.check_html(self.widget(choices=choices), 'choices', '0', html=(
- """<select name="choices">
+ self.check_html(
+ self.widget(choices=choices),
+ "choices",
+ "0",
+ html=(
+ """<select name="choices">
<option value="0" selected>0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="0">extra</option>
</select>"""
- ))
+ ),
+ )
def test_constructor_attrs(self):
"""
Select options shouldn't inherit the parent widget attrs.
"""
widget = Select(
- attrs={'class': 'super', 'id': 'super'},
+ attrs={"class": "super", "id": "super"},
choices=[(1, 1), (2, 2), (3, 3)],
)
- self.check_html(widget, 'num', 2, html=(
- """<select name="num" class="super" id="super">
+ self.check_html(
+ widget,
+ "num",
+ 2,
+ html=(
+ """<select name="num" class="super" id="super">
<option value="1">1</option>
<option value="2" selected>2</option>
<option value="3">3</option>
</select>"""
- ))
+ ),
+ )
def test_compare_to_str(self):
"""
The value is compared to its str().
"""
self.check_html(
- self.widget(choices=[('1', '1'), ('2', '2'), ('3', '3')]),
- 'num', 2,
+ self.widget(choices=[("1", "1"), ("2", "2"), ("3", "3")]),
+ "num",
+ 2,
html=(
"""<select name="num">
<option value="1">1</option>
@@ -101,7 +129,8 @@ class SelectTest(WidgetTest):
)
self.check_html(
self.widget(choices=[(1, 1), (2, 2), (3, 3)]),
- 'num', '2',
+ "num",
+ "2",
html=(
"""<select name="num">
<option value="1">1</option>
@@ -112,7 +141,8 @@ class SelectTest(WidgetTest):
)
self.check_html(
self.widget(choices=[(1, 1), (2, 2), (3, 3)]),
- 'num', 2,
+ "num",
+ 2,
html=(
"""<select name="num">
<option value="1">1</option>
@@ -124,56 +154,78 @@ class SelectTest(WidgetTest):
def test_choices_constructor(self):
widget = Select(choices=[(1, 1), (2, 2), (3, 3)])
- self.check_html(widget, 'num', 2, html=(
- """<select name="num">
+ self.check_html(
+ widget,
+ "num",
+ 2,
+ html=(
+ """<select name="num">
<option value="1">1</option>
<option value="2" selected>2</option>
<option value="3">3</option>
</select>"""
- ))
+ ),
+ )
def test_choices_constructor_generator(self):
"""
If choices is passed to the constructor and is a generator, it can be
iterated over multiple times without getting consumed.
"""
+
def get_choices():
for i in range(5):
yield (i, i)
widget = Select(choices=get_choices())
- self.check_html(widget, 'num', 2, html=(
- """<select name="num">
+ self.check_html(
+ widget,
+ "num",
+ 2,
+ html=(
+ """<select name="num">
<option value="0">0</option>
<option value="1">1</option>
<option value="2" selected>2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>"""
- ))
- self.check_html(widget, 'num', 3, html=(
- """<select name="num">
+ ),
+ )
+ self.check_html(
+ widget,
+ "num",
+ 3,
+ html=(
+ """<select name="num">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3" selected>3</option>
<option value="4">4</option>
</select>"""
- ))
+ ),
+ )
def test_choices_escaping(self):
- choices = (('bad', 'you & me'), ('good', mark_safe('you &gt; me')))
- self.check_html(self.widget(choices=choices), 'escape', None, html=(
- """<select name="escape">
+ choices = (("bad", "you & me"), ("good", mark_safe("you &gt; me")))
+ self.check_html(
+ self.widget(choices=choices),
+ "escape",
+ None,
+ html=(
+ """<select name="escape">
<option value="bad">you &amp; me</option>
<option value="good">you &gt; me</option>
</select>"""
- ))
+ ),
+ )
def test_choices_unicode(self):
self.check_html(
- self.widget(choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]),
- 'email', 'ŠĐĆŽćžšđ',
+ self.widget(choices=[("ŠĐĆŽćžšđ", "ŠĐabcĆŽćžšđ"), ("ćžšđ", "abcćžšđ")]),
+ "email",
+ "ŠĐĆŽćžšđ",
html=(
"""<select name="email">
<option value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" selected>
@@ -188,44 +240,59 @@ class SelectTest(WidgetTest):
"""
Choices can be nested one level in order to create HTML optgroups.
"""
- self.check_html(self.nested_widget, 'nestchoice', None, html=(
- """<select name="nestchoice">
+ self.check_html(
+ self.nested_widget,
+ "nestchoice",
+ None,
+ html=(
+ """<select name="nestchoice">
<option value="outer1">Outer 1</option>
<optgroup label="Group &quot;1&quot;">
<option value="inner1">Inner 1</option>
<option value="inner2">Inner 2</option>
</optgroup>
</select>"""
- ))
+ ),
+ )
def test_choices_select_outer(self):
- self.check_html(self.nested_widget, 'nestchoice', 'outer1', html=(
- """<select name="nestchoice">
+ self.check_html(
+ self.nested_widget,
+ "nestchoice",
+ "outer1",
+ html=(
+ """<select name="nestchoice">
<option value="outer1" selected>Outer 1</option>
<optgroup label="Group &quot;1&quot;">
<option value="inner1">Inner 1</option>
<option value="inner2">Inner 2</option>
</optgroup>
</select>"""
- ))
+ ),
+ )
def test_choices_select_inner(self):
- self.check_html(self.nested_widget, 'nestchoice', 'inner1', html=(
- """<select name="nestchoice">
+ self.check_html(
+ self.nested_widget,
+ "nestchoice",
+ "inner1",
+ html=(
+ """<select name="nestchoice">
<option value="outer1">Outer 1</option>
<optgroup label="Group &quot;1&quot;">
<option value="inner1" selected>Inner 1</option>
<option value="inner2">Inner 2</option>
</optgroup>
</select>"""
- ))
+ ),
+ )
@override_settings(USE_THOUSAND_SEPARATOR=True)
def test_doesnt_localize_option_value(self):
choices = [
- (1, 'One'),
- (1000, 'One thousand'),
- (1000000, 'One million'),
+ (1, "One"),
+ (1000, "One thousand"),
+ (1000000, "One million"),
]
html = """
<select name="number">
@@ -234,11 +301,11 @@ class SelectTest(WidgetTest):
<option value="1000000">One million</option>
</select>
"""
- self.check_html(self.widget(choices=choices), 'number', None, html=html)
+ self.check_html(self.widget(choices=choices), "number", None, html=html)
choices = [
- (datetime.time(0, 0), 'midnight'),
- (datetime.time(12, 0), 'noon'),
+ (datetime.time(0, 0), "midnight"),
+ (datetime.time(12, 0), "noon"),
]
html = """
<select name="time">
@@ -246,118 +313,142 @@ class SelectTest(WidgetTest):
<option value="12:00:00">noon</option>
</select>
"""
- self.check_html(self.widget(choices=choices), 'time', None, html=html)
+ self.check_html(self.widget(choices=choices), "time", None, html=html)
def test_options(self):
- options = list(self.widget(choices=self.beatles).options(
- 'name', ['J'], attrs={'class': 'super'},
- ))
+ options = list(
+ self.widget(choices=self.beatles).options(
+ "name",
+ ["J"],
+ attrs={"class": "super"},
+ )
+ )
self.assertEqual(len(options), 4)
- self.assertEqual(options[0]['name'], 'name')
- self.assertEqual(options[0]['value'], 'J')
- self.assertEqual(options[0]['label'], 'John')
- self.assertEqual(options[0]['index'], '0')
- self.assertIs(options[0]['selected'], True)
+ self.assertEqual(options[0]["name"], "name")
+ self.assertEqual(options[0]["value"], "J")
+ self.assertEqual(options[0]["label"], "John")
+ self.assertEqual(options[0]["index"], "0")
+ self.assertIs(options[0]["selected"], True)
# Template-related attributes
- self.assertEqual(options[1]['name'], 'name')
- self.assertEqual(options[1]['value'], 'P')
- self.assertEqual(options[1]['label'], 'Paul')
- self.assertEqual(options[1]['index'], '1')
- self.assertIs(options[1]['selected'], False)
+ self.assertEqual(options[1]["name"], "name")
+ self.assertEqual(options[1]["value"], "P")
+ self.assertEqual(options[1]["label"], "Paul")
+ self.assertEqual(options[1]["index"], "1")
+ self.assertIs(options[1]["selected"], False)
def test_optgroups(self):
choices = [
- ('Audio', [
- ('vinyl', 'Vinyl'),
- ('cd', 'CD'),
- ]),
- ('Video', [
- ('vhs', 'VHS Tape'),
- ('dvd', 'DVD'),
- ]),
- ('unknown', 'Unknown'),
+ (
+ "Audio",
+ [
+ ("vinyl", "Vinyl"),
+ ("cd", "CD"),
+ ],
+ ),
+ (
+ "Video",
+ [
+ ("vhs", "VHS Tape"),
+ ("dvd", "DVD"),
+ ],
+ ),
+ ("unknown", "Unknown"),
]
- groups = list(self.widget(choices=choices).optgroups(
- 'name', ['vhs'], attrs={'class': 'super'},
- ))
+ groups = list(
+ self.widget(choices=choices).optgroups(
+ "name",
+ ["vhs"],
+ attrs={"class": "super"},
+ )
+ )
audio, video, unknown = groups
label, options, index = audio
- self.assertEqual(label, 'Audio')
+ self.assertEqual(label, "Audio")
self.assertEqual(
options,
- [{
- 'value': 'vinyl',
- 'type': 'select',
- 'attrs': {},
- 'index': '0_0',
- 'label': 'Vinyl',
- 'template_name': 'django/forms/widgets/select_option.html',
- 'name': 'name',
- 'selected': False,
- 'wrap_label': True,
- }, {
- 'value': 'cd',
- 'type': 'select',
- 'attrs': {},
- 'index': '0_1',
- 'label': 'CD',
- 'template_name': 'django/forms/widgets/select_option.html',
- 'name': 'name',
- 'selected': False,
- 'wrap_label': True,
- }]
+ [
+ {
+ "value": "vinyl",
+ "type": "select",
+ "attrs": {},
+ "index": "0_0",
+ "label": "Vinyl",
+ "template_name": "django/forms/widgets/select_option.html",
+ "name": "name",
+ "selected": False,
+ "wrap_label": True,
+ },
+ {
+ "value": "cd",
+ "type": "select",
+ "attrs": {},
+ "index": "0_1",
+ "label": "CD",
+ "template_name": "django/forms/widgets/select_option.html",
+ "name": "name",
+ "selected": False,
+ "wrap_label": True,
+ },
+ ],
)
self.assertEqual(index, 0)
label, options, index = video
- self.assertEqual(label, 'Video')
+ self.assertEqual(label, "Video")
self.assertEqual(
options,
- [{
- 'value': 'vhs',
- 'template_name': 'django/forms/widgets/select_option.html',
- 'label': 'VHS Tape',
- 'attrs': {'selected': True},
- 'index': '1_0',
- 'name': 'name',
- 'selected': True,
- 'type': 'select',
- 'wrap_label': True,
- }, {
- 'value': 'dvd',
- 'template_name': 'django/forms/widgets/select_option.html',
- 'label': 'DVD',
- 'attrs': {},
- 'index': '1_1',
- 'name': 'name',
- 'selected': False,
- 'type': 'select',
- 'wrap_label': True,
- }]
+ [
+ {
+ "value": "vhs",
+ "template_name": "django/forms/widgets/select_option.html",
+ "label": "VHS Tape",
+ "attrs": {"selected": True},
+ "index": "1_0",
+ "name": "name",
+ "selected": True,
+ "type": "select",
+ "wrap_label": True,
+ },
+ {
+ "value": "dvd",
+ "template_name": "django/forms/widgets/select_option.html",
+ "label": "DVD",
+ "attrs": {},
+ "index": "1_1",
+ "name": "name",
+ "selected": False,
+ "type": "select",
+ "wrap_label": True,
+ },
+ ],
)
self.assertEqual(index, 1)
label, options, index = unknown
self.assertIsNone(label)
self.assertEqual(
options,
- [{
- 'value': 'unknown',
- 'selected': False,
- 'template_name': 'django/forms/widgets/select_option.html',
- 'label': 'Unknown',
- 'attrs': {},
- 'index': '2',
- 'name': 'name',
- 'type': 'select',
- 'wrap_label': True,
- }]
+ [
+ {
+ "value": "unknown",
+ "selected": False,
+ "template_name": "django/forms/widgets/select_option.html",
+ "label": "Unknown",
+ "attrs": {},
+ "index": "2",
+ "name": "name",
+ "type": "select",
+ "wrap_label": True,
+ }
+ ],
)
self.assertEqual(index, 2)
def test_optgroups_integer_choices(self):
"""The option 'value' is the same type as what's in `choices`."""
- groups = list(self.widget(choices=[[0, 'choice text']]).optgroups('name', ['vhs']))
+ groups = list(
+ self.widget(choices=[[0, "choice text"]]).optgroups("name", ["vhs"])
+ )
label, options, index = groups[0]
- self.assertEqual(options[0]['value'], 0)
+ self.assertEqual(options[0]["value"], 0)
def test_deepcopy(self):
"""
@@ -372,19 +463,19 @@ class SelectTest(WidgetTest):
self.assertIsNot(widget.attrs, obj.attrs)
def test_doesnt_render_required_when_impossible_to_select_empty_field(self):
- widget = self.widget(choices=[('J', 'John'), ('P', 'Paul')])
+ widget = self.widget(choices=[("J", "John"), ("P", "Paul")])
self.assertIs(widget.use_required_attribute(initial=None), False)
def test_renders_required_when_possible_to_select_empty_field_str(self):
- widget = self.widget(choices=[('', 'select please'), ('P', 'Paul')])
+ widget = self.widget(choices=[("", "select please"), ("P", "Paul")])
self.assertIs(widget.use_required_attribute(initial=None), True)
def test_renders_required_when_possible_to_select_empty_field_list(self):
- widget = self.widget(choices=[['', 'select please'], ['P', 'Paul']])
+ widget = self.widget(choices=[["", "select please"], ["P", "Paul"]])
self.assertIs(widget.use_required_attribute(initial=None), True)
def test_renders_required_when_possible_to_select_empty_field_none(self):
- widget = self.widget(choices=[(None, 'select please'), ('P', 'Paul')])
+ widget = self.widget(choices=[(None, "select please"), ("P", "Paul")])
self.assertIs(widget.use_required_attribute(initial=None), True)
def test_doesnt_render_required_when_no_choices_are_available(self):
diff --git a/tests/forms_tests/widget_tests/test_selectdatewidget.py b/tests/forms_tests/widget_tests/test_selectdatewidget.py
index 6a922e4e71..de0c35cd5b 100644
--- a/tests/forms_tests/widget_tests/test_selectdatewidget.py
+++ b/tests/forms_tests/widget_tests/test_selectdatewidget.py
@@ -12,12 +12,27 @@ from .base import WidgetTest
class SelectDateWidgetTest(WidgetTest):
maxDiff = None
widget = SelectDateWidget(
- years=('2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016'),
+ years=(
+ "2007",
+ "2008",
+ "2009",
+ "2010",
+ "2011",
+ "2012",
+ "2013",
+ "2014",
+ "2015",
+ "2016",
+ ),
)
def test_render_empty(self):
- self.check_html(self.widget, 'mydate', '', html=(
- """
+ self.check_html(
+ self.widget,
+ "mydate",
+ "",
+ html=(
+ """
<select name="mydate_month" id="id_mydate_month">
<option selected value="">---</option>
<option value="1">January</option>
@@ -83,20 +98,25 @@ class SelectDateWidgetTest(WidgetTest):
<option value="2016">2016</option>
</select>
"""
- ))
+ ),
+ )
def test_render_none(self):
"""
Rendering the None or '' values should yield the same output.
"""
self.assertHTMLEqual(
- self.widget.render('mydate', None),
- self.widget.render('mydate', ''),
+ self.widget.render("mydate", None),
+ self.widget.render("mydate", ""),
)
def test_render_string(self):
- self.check_html(self.widget, 'mydate', '2010-04-15', html=(
- """
+ self.check_html(
+ self.widget,
+ "mydate",
+ "2010-04-15",
+ html=(
+ """
<select name="mydate_month" id="id_mydate_month">
<option value="">---</option>
<option value="1">January</option>
@@ -162,20 +182,25 @@ class SelectDateWidgetTest(WidgetTest):
<option value="2016">2016</option>
</select>
"""
- ))
+ ),
+ )
def test_render_datetime(self):
self.assertHTMLEqual(
- self.widget.render('mydate', date(2010, 4, 15)),
- self.widget.render('mydate', '2010-04-15'),
+ self.widget.render("mydate", date(2010, 4, 15)),
+ self.widget.render("mydate", "2010-04-15"),
)
def test_render_invalid_date(self):
"""
Invalid dates should still render the failed date.
"""
- self.check_html(self.widget, 'mydate', '2010-02-31', html=(
- """
+ self.check_html(
+ self.widget,
+ "mydate",
+ "2010-02-31",
+ html=(
+ """
<select name="mydate_month" id="id_mydate_month">
<option value="">---</option>
<option value="1">January</option>
@@ -241,12 +266,17 @@ class SelectDateWidgetTest(WidgetTest):
<option value="2016">2016</option>
</select>
"""
- ))
+ ),
+ )
def test_custom_months(self):
- widget = SelectDateWidget(months=MONTHS_AP, years=('2013',))
- self.check_html(widget, 'mydate', '', html=(
- """
+ widget = SelectDateWidget(months=MONTHS_AP, years=("2013",))
+ self.check_html(
+ widget,
+ "mydate",
+ "",
+ html=(
+ """
<select name="mydate_month" id="id_mydate_month">
<option selected value="">---</option>
<option value="1">Jan.</option>
@@ -303,7 +333,8 @@ class SelectDateWidgetTest(WidgetTest):
<option value="2013">2013</option>
</select>
"""
- ))
+ ),
+ )
def test_selectdate_required(self):
class GetNotRequiredDate(Form):
@@ -312,20 +343,26 @@ class SelectDateWidgetTest(WidgetTest):
class GetRequiredDate(Form):
mydate = DateField(widget=SelectDateWidget, required=True)
- self.assertFalse(GetNotRequiredDate().fields['mydate'].widget.is_required)
- self.assertTrue(GetRequiredDate().fields['mydate'].widget.is_required)
+ self.assertFalse(GetNotRequiredDate().fields["mydate"].widget.is_required)
+ self.assertTrue(GetRequiredDate().fields["mydate"].widget.is_required)
def test_selectdate_empty_label(self):
- w = SelectDateWidget(years=('2014',), empty_label='empty_label')
+ w = SelectDateWidget(years=("2014",), empty_label="empty_label")
# Rendering the default state with empty_label set as string.
- self.assertInHTML('<option selected value="">empty_label</option>', w.render('mydate', ''), count=3)
+ self.assertInHTML(
+ '<option selected value="">empty_label</option>',
+ w.render("mydate", ""),
+ count=3,
+ )
- w = SelectDateWidget(years=('2014',), empty_label=('empty_year', 'empty_month', 'empty_day'))
+ w = SelectDateWidget(
+ years=("2014",), empty_label=("empty_year", "empty_month", "empty_day")
+ )
# Rendering the default state with empty_label tuple.
self.assertHTMLEqual(
- w.render('mydate', ''),
+ w.render("mydate", ""),
"""
<select name="mydate_month" id="id_mydate_month">
<option selected value="">empty_month</option>
@@ -385,21 +422,36 @@ class SelectDateWidgetTest(WidgetTest):
""",
)
- with self.assertRaisesMessage(ValueError, 'empty_label list/tuple must have 3 elements.'):
- SelectDateWidget(years=('2014',), empty_label=('not enough', 'values'))
+ with self.assertRaisesMessage(
+ ValueError, "empty_label list/tuple must have 3 elements."
+ ):
+ SelectDateWidget(years=("2014",), empty_label=("not enough", "values"))
- @translation.override('nl')
+ @translation.override("nl")
def test_l10n(self):
w = SelectDateWidget(
- years=('2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016')
+ years=(
+ "2007",
+ "2008",
+ "2009",
+ "2010",
+ "2011",
+ "2012",
+ "2013",
+ "2014",
+ "2015",
+ "2016",
+ )
)
self.assertEqual(
- w.value_from_datadict({'date_year': '2010', 'date_month': '8', 'date_day': '13'}, {}, 'date'),
- '13-08-2010',
+ w.value_from_datadict(
+ {"date_year": "2010", "date_month": "8", "date_day": "13"}, {}, "date"
+ ),
+ "13-08-2010",
)
self.assertHTMLEqual(
- w.render('date', '13-08-2010'),
+ w.render("date", "13-08-2010"),
"""
<select name="date_day" id="id_date_day">
<option value="">---</option>
@@ -469,20 +521,24 @@ class SelectDateWidgetTest(WidgetTest):
)
# Even with an invalid date, the widget should reflect the entered value (#17401).
- self.assertEqual(w.render('mydate', '2010-02-30').count('selected'), 3)
+ self.assertEqual(w.render("mydate", "2010-02-30").count("selected"), 3)
# Years before 1900 should work.
- w = SelectDateWidget(years=('1899',))
+ w = SelectDateWidget(years=("1899",))
self.assertEqual(
- w.value_from_datadict({'date_year': '1899', 'date_month': '8', 'date_day': '13'}, {}, 'date'),
- '13-08-1899',
+ w.value_from_datadict(
+ {"date_year": "1899", "date_month": "8", "date_day": "13"}, {}, "date"
+ ),
+ "13-08-1899",
)
# And years before 1000 (demonstrating the need for
# sanitize_strftime_format).
- w = SelectDateWidget(years=('0001',))
+ w = SelectDateWidget(years=("0001",))
self.assertEqual(
- w.value_from_datadict({'date_year': '0001', 'date_month': '8', 'date_day': '13'}, {}, 'date'),
- '13-08-0001',
+ w.value_from_datadict(
+ {"date_year": "0001", "date_month": "8", "date_day": "13"}, {}, "date"
+ ),
+ "13-08-0001",
)
# RemovedInDjango50Warning: When the deprecation ends, remove
@@ -490,77 +546,110 @@ class SelectDateWidgetTest(WidgetTest):
# format-related settings will take precedence over locale-dictated
# formats.
@ignore_warnings(category=RemovedInDjango50Warning)
- @override_settings(USE_L10N=False, DATE_INPUT_FORMATS=['%d.%m.%Y'])
+ @override_settings(USE_L10N=False, DATE_INPUT_FORMATS=["%d.%m.%Y"])
def test_custom_input_format(self):
- w = SelectDateWidget(years=('0001', '1899', '2009', '2010'))
+ w = SelectDateWidget(years=("0001", "1899", "2009", "2010"))
for values, expected_value in (
- (('0001', '8', '13'), '13.08.0001'),
- (('1899', '7', '11'), '11.07.1899'),
- (('2009', '3', '7'), '07.03.2009'),
+ (("0001", "8", "13"), "13.08.0001"),
+ (("1899", "7", "11"), "11.07.1899"),
+ (("2009", "3", "7"), "07.03.2009"),
):
with self.subTest(values=values):
data = {
- 'field_%s' % field: value
- for field, value in zip(('year', 'month', 'day'), values)
+ "field_%s" % field: value
+ for field, value in zip(("year", "month", "day"), values)
}
- self.assertEqual(w.value_from_datadict(data, {}, 'field'), expected_value)
+ self.assertEqual(
+ w.value_from_datadict(data, {}, "field"), expected_value
+ )
expected_dict = {
field: int(value)
- for field, value in zip(('year', 'month', 'day'), values)
+ for field, value in zip(("year", "month", "day"), values)
}
self.assertEqual(w.format_value(expected_value), expected_dict)
def test_format_value(self):
valid_formats = [
- '2000-1-1', '2000-10-15', '2000-01-01',
- '2000-01-0', '2000-0-01', '2000-0-0',
- '0-01-01', '0-01-0', '0-0-01', '0-0-0',
+ "2000-1-1",
+ "2000-10-15",
+ "2000-01-01",
+ "2000-01-0",
+ "2000-0-01",
+ "2000-0-0",
+ "0-01-01",
+ "0-01-0",
+ "0-0-01",
+ "0-0-0",
]
for value in valid_formats:
- year, month, day = (int(x) or '' for x in value.split('-'))
+ year, month, day = (int(x) or "" for x in value.split("-"))
with self.subTest(value=value):
- self.assertEqual(self.widget.format_value(value), {'day': day, 'month': month, 'year': year})
+ self.assertEqual(
+ self.widget.format_value(value),
+ {"day": day, "month": month, "year": year},
+ )
invalid_formats = [
- '2000-01-001', '2000-001-01', '2-01-01', '20-01-01', '200-01-01',
- '20000-01-01',
+ "2000-01-001",
+ "2000-001-01",
+ "2-01-01",
+ "20-01-01",
+ "200-01-01",
+ "20000-01-01",
]
for value in invalid_formats:
with self.subTest(value=value):
- self.assertEqual(self.widget.format_value(value), {'day': None, 'month': None, 'year': None})
+ self.assertEqual(
+ self.widget.format_value(value),
+ {"day": None, "month": None, "year": None},
+ )
def test_value_from_datadict(self):
tests = [
- (('2000', '12', '1'), '2000-12-01'),
- (('', '12', '1'), '0-12-1'),
- (('2000', '', '1'), '2000-0-1'),
- (('2000', '12', ''), '2000-12-0'),
- (('', '', '', ''), None),
- ((None, '12', '1'), None),
- (('2000', None, '1'), None),
- (('2000', '12', None), None),
+ (("2000", "12", "1"), "2000-12-01"),
+ (("", "12", "1"), "0-12-1"),
+ (("2000", "", "1"), "2000-0-1"),
+ (("2000", "12", ""), "2000-12-0"),
+ (("", "", "", ""), None),
+ ((None, "12", "1"), None),
+ (("2000", None, "1"), None),
+ (("2000", "12", None), None),
]
for values, expected in tests:
with self.subTest(values=values):
data = {}
- for field_name, value in zip(('year', 'month', 'day'), values):
+ for field_name, value in zip(("year", "month", "day"), values):
if value is not None:
- data['field_%s' % field_name] = value
- self.assertEqual(self.widget.value_from_datadict(data, {}, 'field'), expected)
+ data["field_%s" % field_name] = value
+ self.assertEqual(
+ self.widget.value_from_datadict(data, {}, "field"), expected
+ )
def test_value_omitted_from_data(self):
- self.assertIs(self.widget.value_omitted_from_data({}, {}, 'field'), True)
- self.assertIs(self.widget.value_omitted_from_data({'field_month': '12'}, {}, 'field'), False)
- self.assertIs(self.widget.value_omitted_from_data({'field_year': '2000'}, {}, 'field'), False)
- self.assertIs(self.widget.value_omitted_from_data({'field_day': '1'}, {}, 'field'), False)
- data = {'field_day': '1', 'field_month': '12', 'field_year': '2000'}
- self.assertIs(self.widget.value_omitted_from_data(data, {}, 'field'), False)
+ self.assertIs(self.widget.value_omitted_from_data({}, {}, "field"), True)
+ self.assertIs(
+ self.widget.value_omitted_from_data({"field_month": "12"}, {}, "field"),
+ False,
+ )
+ self.assertIs(
+ self.widget.value_omitted_from_data({"field_year": "2000"}, {}, "field"),
+ False,
+ )
+ self.assertIs(
+ self.widget.value_omitted_from_data({"field_day": "1"}, {}, "field"), False
+ )
+ data = {"field_day": "1", "field_month": "12", "field_year": "2000"}
+ self.assertIs(self.widget.value_omitted_from_data(data, {}, "field"), False)
@override_settings(USE_THOUSAND_SEPARATOR=True)
def test_years_rendered_without_separator(self):
widget = SelectDateWidget(years=(2007,))
- self.check_html(widget, 'mydate', '', html=(
- """
+ self.check_html(
+ widget,
+ "mydate",
+ "",
+ html=(
+ """
<select name="mydate_month" id="id_mydate_month">
<option selected value="">---</option>
<option value="1">January</option>
@@ -615,4 +704,5 @@ class SelectDateWidgetTest(WidgetTest):
<option value="2007">2007</option>
</select>
"""
- ))
+ ),
+ )
diff --git a/tests/forms_tests/widget_tests/test_selectmultiple.py b/tests/forms_tests/widget_tests/test_selectmultiple.py
index eb144ba4b3..99b53521e7 100644
--- a/tests/forms_tests/widget_tests/test_selectmultiple.py
+++ b/tests/forms_tests/widget_tests/test_selectmultiple.py
@@ -5,134 +5,188 @@ from .base import WidgetTest
class SelectMultipleTest(WidgetTest):
widget = SelectMultiple
- numeric_choices = (('0', '0'), ('1', '1'), ('2', '2'), ('3', '3'), ('0', 'extra'))
+ numeric_choices = (("0", "0"), ("1", "1"), ("2", "2"), ("3", "3"), ("0", "extra"))
def test_format_value(self):
widget = self.widget(choices=self.numeric_choices)
self.assertEqual(widget.format_value(None), [])
- self.assertEqual(widget.format_value(''), [''])
- self.assertEqual(widget.format_value([3, 0, 1]), ['3', '0', '1'])
+ self.assertEqual(widget.format_value(""), [""])
+ self.assertEqual(widget.format_value([3, 0, 1]), ["3", "0", "1"])
def test_render_selected(self):
- self.check_html(self.widget(choices=self.beatles), 'beatles', ['J'], html=(
- """<select multiple name="beatles">
+ self.check_html(
+ self.widget(choices=self.beatles),
+ "beatles",
+ ["J"],
+ html=(
+ """<select multiple name="beatles">
<option value="J" selected>John</option>
<option value="P">Paul</option>
<option value="G">George</option>
<option value="R">Ringo</option>
</select>"""
- ))
+ ),
+ )
def test_render_multiple_selected(self):
- self.check_html(self.widget(choices=self.beatles), 'beatles', ['J', 'P'], html=(
- """<select multiple name="beatles">
+ self.check_html(
+ self.widget(choices=self.beatles),
+ "beatles",
+ ["J", "P"],
+ html=(
+ """<select multiple name="beatles">
<option value="J" selected>John</option>
<option value="P" selected>Paul</option>
<option value="G">George</option>
<option value="R">Ringo</option>
</select>"""
- ))
+ ),
+ )
def test_render_none(self):
"""
If the value is None, none of the options are selected, even if the
choices have an empty option.
"""
- self.check_html(self.widget(choices=(('', 'Unknown'),) + self.beatles), 'beatles', None, html=(
- """<select multiple name="beatles">
+ self.check_html(
+ self.widget(choices=(("", "Unknown"),) + self.beatles),
+ "beatles",
+ None,
+ html=(
+ """<select multiple name="beatles">
<option value="">Unknown</option>
<option value="J">John</option>
<option value="P">Paul</option>
<option value="G">George</option>
<option value="R">Ringo</option>
</select>"""
- ))
+ ),
+ )
def test_render_value_label(self):
"""
If the value corresponds to a label (but not to an option value), none
of the options are selected.
"""
- self.check_html(self.widget(choices=self.beatles), 'beatles', ['John'], html=(
- """<select multiple name="beatles">
+ self.check_html(
+ self.widget(choices=self.beatles),
+ "beatles",
+ ["John"],
+ html=(
+ """<select multiple name="beatles">
<option value="J">John</option>
<option value="P">Paul</option>
<option value="G">George</option>
<option value="R">Ringo</option>
</select>"""
- ))
+ ),
+ )
def test_multiple_options_same_value(self):
"""
Multiple options with the same value can be selected (#8103).
"""
- self.check_html(self.widget(choices=self.numeric_choices), 'choices', ['0'], html=(
- """<select multiple name="choices">
+ self.check_html(
+ self.widget(choices=self.numeric_choices),
+ "choices",
+ ["0"],
+ html=(
+ """<select multiple name="choices">
<option value="0" selected>0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="0" selected>extra</option>
</select>"""
- ))
+ ),
+ )
def test_multiple_values_invalid(self):
"""
If multiple values are given, but some of them are not valid, the valid
ones are selected.
"""
- self.check_html(self.widget(choices=self.beatles), 'beatles', ['J', 'G', 'foo'], html=(
- """<select multiple name="beatles">
+ self.check_html(
+ self.widget(choices=self.beatles),
+ "beatles",
+ ["J", "G", "foo"],
+ html=(
+ """<select multiple name="beatles">
<option value="J" selected>John</option>
<option value="P">Paul</option>
<option value="G" selected>George</option>
<option value="R">Ringo</option>
</select>"""
- ))
+ ),
+ )
def test_compare_string(self):
- choices = [('1', '1'), ('2', '2'), ('3', '3')]
+ choices = [("1", "1"), ("2", "2"), ("3", "3")]
- self.check_html(self.widget(choices=choices), 'nums', [2], html=(
- """<select multiple name="nums">
+ self.check_html(
+ self.widget(choices=choices),
+ "nums",
+ [2],
+ html=(
+ """<select multiple name="nums">
<option value="1">1</option>
<option value="2" selected>2</option>
<option value="3">3</option>
</select>"""
- ))
+ ),
+ )
- self.check_html(self.widget(choices=choices), 'nums', ['2'], html=(
- """<select multiple name="nums">
+ self.check_html(
+ self.widget(choices=choices),
+ "nums",
+ ["2"],
+ html=(
+ """<select multiple name="nums">
<option value="1">1</option>
<option value="2" selected>2</option>
<option value="3">3</option>
</select>"""
- ))
+ ),
+ )
- self.check_html(self.widget(choices=choices), 'nums', [2], html=(
- """<select multiple name="nums">
+ self.check_html(
+ self.widget(choices=choices),
+ "nums",
+ [2],
+ html=(
+ """<select multiple name="nums">
<option value="1">1</option>
<option value="2" selected>2</option>
<option value="3">3</option>
</select>"""
- ))
+ ),
+ )
def test_optgroup_select_multiple(self):
- widget = SelectMultiple(choices=(
- ('outer1', 'Outer 1'),
- ('Group "1"', (('inner1', 'Inner 1'), ('inner2', 'Inner 2'))),
- ))
- self.check_html(widget, 'nestchoice', ['outer1', 'inner2'], html=(
- """<select multiple name="nestchoice">
+ widget = SelectMultiple(
+ choices=(
+ ("outer1", "Outer 1"),
+ ('Group "1"', (("inner1", "Inner 1"), ("inner2", "Inner 2"))),
+ )
+ )
+ self.check_html(
+ widget,
+ "nestchoice",
+ ["outer1", "inner2"],
+ html=(
+ """<select multiple name="nestchoice">
<option value="outer1" selected>Outer 1</option>
<optgroup label="Group &quot;1&quot;">
<option value="inner1">Inner 1</option>
<option value="inner2" selected>Inner 2</option>
</optgroup>
</select>"""
- ))
+ ),
+ )
def test_value_omitted_from_data(self):
widget = self.widget(choices=self.beatles)
- self.assertIs(widget.value_omitted_from_data({}, {}, 'field'), False)
- self.assertIs(widget.value_omitted_from_data({'field': 'value'}, {}, 'field'), False)
+ self.assertIs(widget.value_omitted_from_data({}, {}, "field"), False)
+ self.assertIs(
+ widget.value_omitted_from_data({"field": "value"}, {}, "field"), False
+ )
diff --git a/tests/forms_tests/widget_tests/test_splitdatetimewidget.py b/tests/forms_tests/widget_tests/test_splitdatetimewidget.py
index ebb30da148..ca48505b85 100644
--- a/tests/forms_tests/widget_tests/test_splitdatetimewidget.py
+++ b/tests/forms_tests/widget_tests/test_splitdatetimewidget.py
@@ -9,45 +9,72 @@ class SplitDateTimeWidgetTest(WidgetTest):
widget = SplitDateTimeWidget()
def test_render_empty(self):
- self.check_html(self.widget, 'date', '', html=(
- '<input type="text" name="date_0"><input type="text" name="date_1">'
- ))
+ self.check_html(
+ self.widget,
+ "date",
+ "",
+ html=('<input type="text" name="date_0"><input type="text" name="date_1">'),
+ )
def test_render_none(self):
- self.check_html(self.widget, 'date', None, html=(
- '<input type="text" name="date_0"><input type="text" name="date_1">'
- ))
+ self.check_html(
+ self.widget,
+ "date",
+ None,
+ html=('<input type="text" name="date_0"><input type="text" name="date_1">'),
+ )
def test_render_datetime(self):
- self.check_html(self.widget, 'date', datetime(2006, 1, 10, 7, 30), html=(
- '<input type="text" name="date_0" value="2006-01-10">'
- '<input type="text" name="date_1" value="07:30:00">'
- ))
+ self.check_html(
+ self.widget,
+ "date",
+ datetime(2006, 1, 10, 7, 30),
+ html=(
+ '<input type="text" name="date_0" value="2006-01-10">'
+ '<input type="text" name="date_1" value="07:30:00">'
+ ),
+ )
def test_render_date_and_time(self):
- self.check_html(self.widget, 'date', [date(2006, 1, 10), time(7, 30)], html=(
- '<input type="text" name="date_0" value="2006-01-10">'
- '<input type="text" name="date_1" value="07:30:00">'
- ))
+ self.check_html(
+ self.widget,
+ "date",
+ [date(2006, 1, 10), time(7, 30)],
+ html=(
+ '<input type="text" name="date_0" value="2006-01-10">'
+ '<input type="text" name="date_1" value="07:30:00">'
+ ),
+ )
def test_constructor_attrs(self):
- widget = SplitDateTimeWidget(attrs={'class': 'pretty'})
- self.check_html(widget, 'date', datetime(2006, 1, 10, 7, 30), html=(
- '<input type="text" class="pretty" value="2006-01-10" name="date_0">'
- '<input type="text" class="pretty" value="07:30:00" name="date_1">'
- ))
+ widget = SplitDateTimeWidget(attrs={"class": "pretty"})
+ self.check_html(
+ widget,
+ "date",
+ datetime(2006, 1, 10, 7, 30),
+ html=(
+ '<input type="text" class="pretty" value="2006-01-10" name="date_0">'
+ '<input type="text" class="pretty" value="07:30:00" name="date_1">'
+ ),
+ )
def test_constructor_different_attrs(self):
html = (
'<input type="text" class="foo" value="2006-01-10" name="date_0">'
'<input type="text" class="bar" value="07:30:00" name="date_1">'
)
- widget = SplitDateTimeWidget(date_attrs={'class': 'foo'}, time_attrs={'class': 'bar'})
- self.check_html(widget, 'date', datetime(2006, 1, 10, 7, 30), html=html)
- widget = SplitDateTimeWidget(date_attrs={'class': 'foo'}, attrs={'class': 'bar'})
- self.check_html(widget, 'date', datetime(2006, 1, 10, 7, 30), html=html)
- widget = SplitDateTimeWidget(time_attrs={'class': 'bar'}, attrs={'class': 'foo'})
- self.check_html(widget, 'date', datetime(2006, 1, 10, 7, 30), html=html)
+ widget = SplitDateTimeWidget(
+ date_attrs={"class": "foo"}, time_attrs={"class": "bar"}
+ )
+ self.check_html(widget, "date", datetime(2006, 1, 10, 7, 30), html=html)
+ widget = SplitDateTimeWidget(
+ date_attrs={"class": "foo"}, attrs={"class": "bar"}
+ )
+ self.check_html(widget, "date", datetime(2006, 1, 10, 7, 30), html=html)
+ widget = SplitDateTimeWidget(
+ time_attrs={"class": "bar"}, attrs={"class": "foo"}
+ )
+ self.check_html(widget, "date", datetime(2006, 1, 10, 7, 30), html=html)
def test_formatting(self):
"""
@@ -55,9 +82,15 @@ class SplitDateTimeWidgetTest(WidgetTest):
displayed.
"""
widget = SplitDateTimeWidget(
- date_format='%d/%m/%Y', time_format='%H:%M',
+ date_format="%d/%m/%Y",
+ time_format="%H:%M",
+ )
+ self.check_html(
+ widget,
+ "date",
+ datetime(2006, 1, 10, 7, 30),
+ html=(
+ '<input type="text" name="date_0" value="10/01/2006">'
+ '<input type="text" name="date_1" value="07:30">'
+ ),
)
- self.check_html(widget, 'date', datetime(2006, 1, 10, 7, 30), html=(
- '<input type="text" name="date_0" value="10/01/2006">'
- '<input type="text" name="date_1" value="07:30">'
- ))
diff --git a/tests/forms_tests/widget_tests/test_splithiddendatetimewidget.py b/tests/forms_tests/widget_tests/test_splithiddendatetimewidget.py
index c574eb6f7b..549f8c7754 100644
--- a/tests/forms_tests/widget_tests/test_splithiddendatetimewidget.py
+++ b/tests/forms_tests/widget_tests/test_splithiddendatetimewidget.py
@@ -10,43 +10,74 @@ class SplitHiddenDateTimeWidgetTest(WidgetTest):
widget = SplitHiddenDateTimeWidget()
def test_render_empty(self):
- self.check_html(self.widget, 'date', '', html=(
- '<input type="hidden" name="date_0"><input type="hidden" name="date_1">'
- ))
+ self.check_html(
+ self.widget,
+ "date",
+ "",
+ html=(
+ '<input type="hidden" name="date_0"><input type="hidden" name="date_1">'
+ ),
+ )
def test_render_value(self):
d = datetime(2007, 9, 17, 12, 51, 34, 482548)
- self.check_html(self.widget, 'date', d, html=(
- '<input type="hidden" name="date_0" value="2007-09-17">'
- '<input type="hidden" name="date_1" value="12:51:34">'
- ))
- self.check_html(self.widget, 'date', datetime(2007, 9, 17, 12, 51, 34), html=(
- '<input type="hidden" name="date_0" value="2007-09-17">'
- '<input type="hidden" name="date_1" value="12:51:34">'
- ))
- self.check_html(self.widget, 'date', datetime(2007, 9, 17, 12, 51), html=(
- '<input type="hidden" name="date_0" value="2007-09-17">'
- '<input type="hidden" name="date_1" value="12:51:00">'
- ))
+ self.check_html(
+ self.widget,
+ "date",
+ d,
+ html=(
+ '<input type="hidden" name="date_0" value="2007-09-17">'
+ '<input type="hidden" name="date_1" value="12:51:34">'
+ ),
+ )
+ self.check_html(
+ self.widget,
+ "date",
+ datetime(2007, 9, 17, 12, 51, 34),
+ html=(
+ '<input type="hidden" name="date_0" value="2007-09-17">'
+ '<input type="hidden" name="date_1" value="12:51:34">'
+ ),
+ )
+ self.check_html(
+ self.widget,
+ "date",
+ datetime(2007, 9, 17, 12, 51),
+ html=(
+ '<input type="hidden" name="date_0" value="2007-09-17">'
+ '<input type="hidden" name="date_1" value="12:51:00">'
+ ),
+ )
- @translation.override('de-at')
+ @translation.override("de-at")
def test_l10n(self):
d = datetime(2007, 9, 17, 12, 51)
- self.check_html(self.widget, 'date', d, html=(
- """
+ self.check_html(
+ self.widget,
+ "date",
+ d,
+ html=(
+ """
<input type="hidden" name="date_0" value="17.09.2007">
<input type="hidden" name="date_1" value="12:51:00">
"""
- ))
+ ),
+ )
def test_constructor_different_attrs(self):
html = (
'<input type="hidden" class="foo" value="2006-01-10" name="date_0">'
'<input type="hidden" class="bar" value="07:30:00" name="date_1">'
)
- widget = SplitHiddenDateTimeWidget(date_attrs={'class': 'foo'}, time_attrs={'class': 'bar'})
- self.check_html(widget, 'date', datetime(2006, 1, 10, 7, 30), html=html)
- widget = SplitHiddenDateTimeWidget(date_attrs={'class': 'foo'}, attrs={'class': 'bar'})
- self.check_html(widget, 'date', datetime(2006, 1, 10, 7, 30), html=html)
- widget = SplitHiddenDateTimeWidget(time_attrs={'class': 'bar'}, attrs={'class': 'foo'})
- self.check_html(widget, 'date', datetime(2006, 1, 10, 7, 30), html=html)
+ widget = SplitHiddenDateTimeWidget(
+ date_attrs={"class": "foo"}, time_attrs={"class": "bar"}
+ )
+ self.check_html(widget, "date", datetime(2006, 1, 10, 7, 30), html=html)
+ widget = SplitHiddenDateTimeWidget(
+ date_attrs={"class": "foo"}, attrs={"class": "bar"}
+ )
+ self.check_html(widget, "date", datetime(2006, 1, 10, 7, 30), html=html)
+ widget = SplitHiddenDateTimeWidget(
+ time_attrs={"class": "bar"}, attrs={"class": "foo"}
+ )
+ self.check_html(widget, "date", datetime(2006, 1, 10, 7, 30), html=html)
diff --git a/tests/forms_tests/widget_tests/test_textarea.py b/tests/forms_tests/widget_tests/test_textarea.py
index 490848fab3..e92dfc51f4 100644
--- a/tests/forms_tests/widget_tests/test_textarea.py
+++ b/tests/forms_tests/widget_tests/test_textarea.py
@@ -8,27 +8,55 @@ class TextareaTest(WidgetTest):
widget = Textarea()
def test_render(self):
- self.check_html(self.widget, 'msg', 'value', html=(
- '<textarea rows="10" cols="40" name="msg">value</textarea>'
- ))
+ self.check_html(
+ self.widget,
+ "msg",
+ "value",
+ html=('<textarea rows="10" cols="40" name="msg">value</textarea>'),
+ )
def test_render_required(self):
widget = Textarea()
widget.is_required = True
- self.check_html(widget, 'msg', 'value', html='<textarea rows="10" cols="40" name="msg">value</textarea>')
+ self.check_html(
+ widget,
+ "msg",
+ "value",
+ html='<textarea rows="10" cols="40" name="msg">value</textarea>',
+ )
def test_render_empty(self):
- self.check_html(self.widget, 'msg', '', html='<textarea rows="10" cols="40" name="msg"></textarea>')
+ self.check_html(
+ self.widget,
+ "msg",
+ "",
+ html='<textarea rows="10" cols="40" name="msg"></textarea>',
+ )
def test_render_none(self):
- self.check_html(self.widget, 'msg', None, html='<textarea rows="10" cols="40" name="msg"></textarea>')
+ self.check_html(
+ self.widget,
+ "msg",
+ None,
+ html='<textarea rows="10" cols="40" name="msg"></textarea>',
+ )
def test_escaping(self):
- self.check_html(self.widget, 'msg', 'some "quoted" & ampersanded value', html=(
- '<textarea rows="10" cols="40" name="msg">some &quot;quoted&quot; &amp; ampersanded value</textarea>'
- ))
+ self.check_html(
+ self.widget,
+ "msg",
+ 'some "quoted" & ampersanded value',
+ html=(
+ '<textarea rows="10" cols="40" name="msg">some &quot;quoted&quot; &amp; ampersanded value</textarea>'
+ ),
+ )
def test_mark_safe(self):
- self.check_html(self.widget, 'msg', mark_safe('pre &quot;quoted&quot; value'), html=(
- '<textarea rows="10" cols="40" name="msg">pre &quot;quoted&quot; value</textarea>'
- ))
+ self.check_html(
+ self.widget,
+ "msg",
+ mark_safe("pre &quot;quoted&quot; value"),
+ html=(
+ '<textarea rows="10" cols="40" name="msg">pre &quot;quoted&quot; value</textarea>'
+ ),
+ )
diff --git a/tests/forms_tests/widget_tests/test_textinput.py b/tests/forms_tests/widget_tests/test_textinput.py
index 260e86f740..52ffabec65 100644
--- a/tests/forms_tests/widget_tests/test_textinput.py
+++ b/tests/forms_tests/widget_tests/test_textinput.py
@@ -8,43 +8,64 @@ class TextInputTest(WidgetTest):
widget = TextInput()
def test_render(self):
- self.check_html(self.widget, 'email', '', html='<input type="text" name="email">')
+ self.check_html(
+ self.widget, "email", "", html='<input type="text" name="email">'
+ )
def test_render_none(self):
- self.check_html(self.widget, 'email', None, html='<input type="text" name="email">')
+ self.check_html(
+ self.widget, "email", None, html='<input type="text" name="email">'
+ )
def test_render_value(self):
- self.check_html(self.widget, 'email', 'test@example.com', html=(
- '<input type="text" name="email" value="test@example.com">'
- ))
+ self.check_html(
+ self.widget,
+ "email",
+ "test@example.com",
+ html=('<input type="text" name="email" value="test@example.com">'),
+ )
def test_render_boolean(self):
"""
Boolean values are rendered to their string forms ("True" and
"False").
"""
- self.check_html(self.widget, 'get_spam', False, html=(
- '<input type="text" name="get_spam" value="False">'
- ))
- self.check_html(self.widget, 'get_spam', True, html=(
- '<input type="text" name="get_spam" value="True">'
- ))
+ self.check_html(
+ self.widget,
+ "get_spam",
+ False,
+ html=('<input type="text" name="get_spam" value="False">'),
+ )
+ self.check_html(
+ self.widget,
+ "get_spam",
+ True,
+ html=('<input type="text" name="get_spam" value="True">'),
+ )
def test_render_quoted(self):
self.check_html(
- self.widget, 'email', 'some "quoted" & ampersanded value',
+ self.widget,
+ "email",
+ 'some "quoted" & ampersanded value',
html='<input type="text" name="email" value="some &quot;quoted&quot; &amp; ampersanded value">',
)
def test_render_custom_attrs(self):
self.check_html(
- self.widget, 'email', 'test@example.com', attrs={'class': 'fun'},
+ self.widget,
+ "email",
+ "test@example.com",
+ attrs={"class": "fun"},
html='<input type="text" name="email" value="test@example.com" class="fun">',
)
def test_render_unicode(self):
self.check_html(
- self.widget, 'email', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'},
+ self.widget,
+ "email",
+ "ŠĐĆŽćžšđ",
+ attrs={"class": "fun"},
html=(
'<input type="text" name="email" '
'value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" class="fun">'
@@ -52,10 +73,14 @@ class TextInputTest(WidgetTest):
)
def test_constructor_attrs(self):
- widget = TextInput(attrs={'class': 'fun', 'type': 'email'})
- self.check_html(widget, 'email', '', html='<input type="email" class="fun" name="email">')
+ widget = TextInput(attrs={"class": "fun", "type": "email"})
self.check_html(
- widget, 'email', 'foo@example.com',
+ widget, "email", "", html='<input type="email" class="fun" name="email">'
+ )
+ self.check_html(
+ widget,
+ "email",
+ "foo@example.com",
html='<input type="email" class="fun" value="foo@example.com" name="email">',
)
@@ -64,18 +89,26 @@ class TextInputTest(WidgetTest):
`attrs` passed to render() get precedence over those passed to the
constructor
"""
- widget = TextInput(attrs={'class': 'pretty'})
+ widget = TextInput(attrs={"class": "pretty"})
self.check_html(
- widget, 'email', '', attrs={'class': 'special'},
+ widget,
+ "email",
+ "",
+ attrs={"class": "special"},
html='<input type="text" class="special" name="email">',
)
def test_attrs_safestring(self):
- widget = TextInput(attrs={'onBlur': mark_safe("function('foo')")})
- self.check_html(widget, 'email', '', html='<input onBlur="function(\'foo\')" type="text" name="email">')
+ widget = TextInput(attrs={"onBlur": mark_safe("function('foo')")})
+ self.check_html(
+ widget,
+ "email",
+ "",
+ html='<input onBlur="function(\'foo\')" type="text" name="email">',
+ )
def test_use_required_attribute(self):
# Text inputs can safely trigger the browser validation.
self.assertIs(self.widget.use_required_attribute(None), True)
- self.assertIs(self.widget.use_required_attribute(''), True)
- self.assertIs(self.widget.use_required_attribute('resume.txt'), True)
+ self.assertIs(self.widget.use_required_attribute(""), True)
+ self.assertIs(self.widget.use_required_attribute("resume.txt"), True)
diff --git a/tests/forms_tests/widget_tests/test_timeinput.py b/tests/forms_tests/widget_tests/test_timeinput.py
index 6060168eb3..6f56a07f5e 100644
--- a/tests/forms_tests/widget_tests/test_timeinput.py
+++ b/tests/forms_tests/widget_tests/test_timeinput.py
@@ -10,37 +10,60 @@ class TimeInputTest(WidgetTest):
widget = TimeInput()
def test_render_none(self):
- self.check_html(self.widget, 'time', None, html='<input type="text" name="time">')
+ self.check_html(
+ self.widget, "time", None, html='<input type="text" name="time">'
+ )
def test_render_value(self):
"""
The microseconds are trimmed on display, by default.
"""
t = time(12, 51, 34, 482548)
- self.assertEqual(str(t), '12:51:34.482548')
- self.check_html(self.widget, 'time', t, html='<input type="text" name="time" value="12:51:34">')
- self.check_html(self.widget, 'time', time(12, 51, 34), html=(
- '<input type="text" name="time" value="12:51:34">'
- ))
- self.check_html(self.widget, 'time', time(12, 51), html=(
- '<input type="text" name="time" value="12:51:00">'
- ))
+ self.assertEqual(str(t), "12:51:34.482548")
+ self.check_html(
+ self.widget,
+ "time",
+ t,
+ html='<input type="text" name="time" value="12:51:34">',
+ )
+ self.check_html(
+ self.widget,
+ "time",
+ time(12, 51, 34),
+ html=('<input type="text" name="time" value="12:51:34">'),
+ )
+ self.check_html(
+ self.widget,
+ "time",
+ time(12, 51),
+ html=('<input type="text" name="time" value="12:51:00">'),
+ )
def test_string(self):
"""Initializing from a string value."""
- self.check_html(self.widget, 'time', '13:12:11', html=(
- '<input type="text" name="time" value="13:12:11">'
- ))
+ self.check_html(
+ self.widget,
+ "time",
+ "13:12:11",
+ html=('<input type="text" name="time" value="13:12:11">'),
+ )
def test_format(self):
"""
Use 'format' to change the way a value is displayed.
"""
t = time(12, 51, 34, 482548)
- widget = TimeInput(format='%H:%M', attrs={'type': 'time'})
- self.check_html(widget, 'time', t, html='<input type="time" name="time" value="12:51">')
+ widget = TimeInput(format="%H:%M", attrs={"type": "time"})
+ self.check_html(
+ widget, "time", t, html='<input type="time" name="time" value="12:51">'
+ )
- @translation.override('de-at')
+ @translation.override("de-at")
def test_l10n(self):
t = time(12, 51, 34, 482548)
- self.check_html(self.widget, 'time', t, html='<input type="text" name="time" value="12:51:34">')
+ self.check_html(
+ self.widget,
+ "time",
+ t,
+ html='<input type="text" name="time" value="12:51:34">',
+ )
diff --git a/tests/forms_tests/widget_tests/test_widget.py b/tests/forms_tests/widget_tests/test_widget.py
index 8cde388b8f..9e243570d7 100644
--- a/tests/forms_tests/widget_tests/test_widget.py
+++ b/tests/forms_tests/widget_tests/test_widget.py
@@ -5,22 +5,29 @@ from .base import WidgetTest
class WidgetTests(WidgetTest):
-
def test_format_value(self):
widget = Widget()
self.assertIsNone(widget.format_value(None))
- self.assertIsNone(widget.format_value(''))
- self.assertEqual(widget.format_value('español'), 'español')
- self.assertEqual(widget.format_value(42.5), '42.5')
+ self.assertIsNone(widget.format_value(""))
+ self.assertEqual(widget.format_value("español"), "español")
+ self.assertEqual(widget.format_value(42.5), "42.5")
def test_value_omitted_from_data(self):
widget = Widget()
- self.assertIs(widget.value_omitted_from_data({}, {}, 'field'), True)
- self.assertIs(widget.value_omitted_from_data({'field': 'value'}, {}, 'field'), False)
+ self.assertIs(widget.value_omitted_from_data({}, {}, "field"), True)
+ self.assertIs(
+ widget.value_omitted_from_data({"field": "value"}, {}, "field"), False
+ )
def test_no_trailing_newline_in_attrs(self):
- self.check_html(Input(), 'name', 'value', strict=True, html='<input type="None" name="name" value="value">')
+ self.check_html(
+ Input(),
+ "name",
+ "value",
+ strict=True,
+ html='<input type="None" name="name" value="value">',
+ )
def test_attr_false_not_rendered(self):
html = '<input type="None" name="name" value="value">'
- self.check_html(Input(), 'name', 'value', html=html, attrs={'readonly': False})
+ self.check_html(Input(), "name", "value", html=html, attrs={"readonly": False})