Refs -- Added MultiValueField test for rendering of optional subfields.
@@ -10,9 +10,10 @@ from django.forms import (
BooleanField, CharField, CheckboxSelectMultiple, ChoiceField, DateField,
DateTimeField, EmailField, FileField, FileInput, FloatField, Form,
HiddenInput, ImageField, IntegerField, MultipleChoiceField,
- MultipleHiddenInput, MultiValueField, NullBooleanField, PasswordInput,
- RadioSelect, Select, SplitDateTimeField, SplitHiddenDateTimeWidget,
- Textarea, TextInput, TimeField, ValidationError, forms,
+ MultipleHiddenInput, MultiValueField, MultiWidget, NullBooleanField,
+ PasswordInput, RadioSelect, Select, SplitDateTimeField,
+ SplitHiddenDateTimeWidget, Textarea, TextInput, TimeField, ValidationError,
+ forms,
)
from django.forms.renderers import DjangoTemplates, get_default_renderer
from django.forms.utils import ErrorList
@@ -3102,6 +3103,39 @@ Good luck picking a username that doesn&#x27;t already exist.</p>
with self.assertRaisesMessage(ValidationError, "'Enter a valid country code.'"):
f.clean(['61', '287654321', '123', 'Home'])
+ def test_multivalue_optional_subfields_rendering(self):
+ class PhoneWidget(MultiWidget):
+ def __init__(self, attrs=None):
+ widgets = [TextInput(), TextInput()]
+ super().__init__(widgets, attrs)
+
+ def decompress(self, value):
+ return [None, None]
+
+ class PhoneField(MultiValueField):
+ def __init__(self, *args, **kwargs):
+ fields = [CharField(), CharField(required=False)]
+ super().__init__(fields, *args, **kwargs)
+
+ class PhoneForm(Form):
+ phone1 = PhoneField(widget=PhoneWidget)
+ phone2 = PhoneField(widget=PhoneWidget, required=False)
+ phone3 = PhoneField(widget=PhoneWidget, require_all_fields=False)
+ phone4 = PhoneField(
+ widget=PhoneWidget, required=False, require_all_fields=False,
+ )
+
+ form = PhoneForm(auto_id=False)
+ self.assertHTMLEqual(
+ form.as_p(),
+ """
+ <p>Phone1:<input type="text" name="phone1_0" required><input type="text" name="phone1_1" required></p>
+ <p>Phone2:<input type="text" name="phone2_0"><input type="text" name="phone2_1"></p>
+ <p>Phone3:<input type="text" name="phone3_0" required><input type="text" name="phone3_1"></p>
+ <p>Phone4:<input type="text" name="phone4_0"><input type="text" name="phone4_1"></p>
+ """,
+ )
+
def test_custom_empty_values(self):
"""
Form fields can customize what is considered as an empty value
