diff --git a/django/forms/fields.py b/django/forms/fields.py index 2019a43c73..3b15c1b021 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -970,6 +970,8 @@ class MultiValueField(Field): for f in fields: f.error_messages.setdefault('incomplete', self.error_messages['incomplete']) + if self.disabled: + f.disabled = True if self.require_all_fields: # Set 'required' to False on the individual fields, because the # required validation will be handled by MultiValueField, not @@ -996,6 +998,8 @@ class MultiValueField(Field): """ clean_data = [] errors = [] + if self.disabled and not isinstance(value, list): + value = self.widget.decompress(value) if not value or isinstance(value, (list, tuple)): if not value or not [v for v in value if v not in self.empty_values]: if self.required: diff --git a/tests/forms_tests/field_tests/test_multivaluefield.py b/tests/forms_tests/field_tests/test_multivaluefield.py index e77bb0df26..cd446d07ce 100644 --- a/tests/forms_tests/field_tests/test_multivaluefield.py +++ b/tests/forms_tests/field_tests/test_multivaluefield.py @@ -62,6 +62,21 @@ class MultiValueFieldTest(SimpleTestCase): 'some text,JP,2007-04-25 06:24:00', ) + def test_clean_disabled_multivalue(self): + class ComplexFieldForm(Form): + 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']], + ) + for data in inputs: + with self.subTest(data=data): + form = ComplexFieldForm({}, initial={'f': data}) + form.full_clean() + self.assertEqual(form.errors, {}) + 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):