diff options
Diffstat (limited to 'tests/forms_tests')
| -rw-r--r-- | tests/forms_tests/tests/test_forms.py | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py index b41424d43d..20c86754c6 100644 --- a/tests/forms_tests/tests/test_forms.py +++ b/tests/forms_tests/tests/test_forms.py @@ -8,6 +8,7 @@ from django.core.files.uploadedfile import SimpleUploadedFile from django.core.validators import MaxValueValidator, RegexValidator from django.forms import ( BooleanField, + BoundField, CharField, CheckboxSelectMultiple, ChoiceField, @@ -4971,6 +4972,22 @@ class RendererTests(SimpleTestCase): context = form.get_context() self.assertEqual(context["errors"].renderer, custom) + def test_boundfield_fallback(self): + class RendererWithoutBoundFieldClassAttribute: + form_template_name = "django/forms/div.html" + formset_template_name = "django/forms/formsets/div.html" + field_template_name = "django/forms/field.html" + + def render(self, template_name, context, request=None): + return "Nice" + + class UserForm(Form): + name = CharField() + + form = UserForm(renderer=RendererWithoutBoundFieldClassAttribute()) + self.assertIsInstance(form["name"], BoundField) + self.assertEqual(form["name"].as_field_group(), "Nice") + class TemplateTests(SimpleTestCase): def test_iterate_radios(self): @@ -5473,3 +5490,146 @@ class OverrideTests(SimpleTestCase): '<label for="id_name" class="required">Name:</label>' '<legend class="required">Language:</legend>', ) + + +class BoundFieldWithoutColon(BoundField): + def label_tag(self, contents=None, attrs=None, label_suffix=None, tag=None): + return super().label_tag( + contents=contents, attrs=attrs, label_suffix="", tag=None + ) + + +class BoundFieldWithTwoColons(BoundField): + def label_tag(self, contents=None, attrs=None, label_suffix=None, tag=None): + return super().label_tag( + contents=contents, attrs=attrs, label_suffix="::", tag=None + ) + + +class BoundFieldWithCustomClass(BoundField): + def label_tag(self, contents=None, attrs=None, label_suffix=None, tag=None): + attrs = attrs or {} + attrs["class"] = "custom-class" + return super().label_tag(contents, attrs, label_suffix, tag) + + +class BoundFieldWithWrappingClass(BoundField): + def css_classes(self, extra_classes=None): + parent_classes = super().css_classes(extra_classes) + return f"field-class {parent_classes}" + + +class BoundFieldOverrideRenderer(DjangoTemplates): + bound_field_class = BoundFieldWithoutColon + + +@override_settings( + FORM_RENDERER="forms_tests.tests.test_forms.BoundFieldOverrideRenderer" +) +class CustomBoundFieldTest(SimpleTestCase): + def test_renderer_custom_bound_field(self): + t = Template("{{ form }}") + html = t.render(Context({"form": Person()})) + expected = """ + <div><label for="id_first_name">First name</label> + <input type="text" name="first_name" required + id="id_first_name"></div> + <div><label for="id_last_name">Last name</label> + <input type="text" name="last_name" required + id="id_last_name"></div><div> + <label for="id_birthday">Birthday</label> + <input type="text" name="birthday" required + id="id_birthday"></div>""" + self.assertHTMLEqual(html, expected) + + def test_form_custom_boundfield(self): + class CustomBoundFieldPerson(Person): + bound_field_class = BoundFieldWithTwoColons + + with self.subTest("form's BoundField takes over renderer's BoundField"): + t = Template("{{ form }}") + html = t.render(Context({"form": CustomBoundFieldPerson()})) + expected = """ + <div><label for="id_first_name">First name::</label> + <input type="text" name="first_name" required + id="id_first_name"></div> + <div><label for="id_last_name">Last name::</label> + <input type="text" name="last_name" required + id="id_last_name"></div><div> + <label for="id_birthday">Birthday::</label> + <input type="text" name="birthday" required + id="id_birthday"></div>""" + self.assertHTMLEqual(html, expected) + + with self.subTest("Constructor argument takes over class property"): + t = Template("{{ form }}") + html = t.render( + Context( + { + "form": CustomBoundFieldPerson( + bound_field_class=BoundFieldWithCustomClass + ) + } + ) + ) + expected = """ + <div><label class="custom-class" for="id_first_name">First name:</label> + <input type="text" name="first_name" required + id="id_first_name"></div> + <div><label class="custom-class" for="id_last_name">Last name:</label> + <input type="text" name="last_name" required + id="id_last_name"></div><div> + <label class="custom-class" for="id_birthday">Birthday:</label> + <input type="text" name="birthday" required + id="id_birthday"></div>""" + self.assertHTMLEqual(html, expected) + + with self.subTest("Overriding css_classes works as expected"): + t = Template("{{ form }}") + html = t.render( + Context( + { + "form": CustomBoundFieldPerson( + bound_field_class=BoundFieldWithWrappingClass + ) + } + ) + ) + expected = """ + <div class="field-class"><label for="id_first_name">First name:</label> + <input type="text" name="first_name" required + id="id_first_name"></div> + <div class="field-class"><label for="id_last_name">Last name:</label> + <input type="text" name="last_name" required + id="id_last_name"></div><div class="field-class"> + <label for="id_birthday">Birthday:</label> + <input type="text" name="birthday" required + id="id_birthday"></div>""" + self.assertHTMLEqual(html, expected) + + def test_field_custom_bound_field(self): + class BoundFieldWithTwoColonsCharField(CharField): + bound_field_class = BoundFieldWithTwoColons + + class CustomFieldBoundFieldPerson(Person): + bound_field_class = BoundField + + first_name = BoundFieldWithTwoColonsCharField() + last_name = BoundFieldWithTwoColonsCharField( + bound_field_class=BoundFieldWithCustomClass + ) + + html = Template("{{ form }}").render( + Context({"form": CustomFieldBoundFieldPerson()}) + ) + expected = """ + <div><label for="id_first_name">First name::</label> + <input type="text" name="first_name" required + id="id_first_name"></div> + <div><label class="custom-class" for="id_last_name">Last name:</label> + <input type="text" name="last_name" required + id="id_last_name"></div><div> + <label for="id_birthday">Birthday:</label> + <input type="text" name="birthday" required + id="id_birthday"></div>""" + self.assertHTMLEqual(html, expected) |
