From ec2ce4517ac89f6c6334fe5322d1fc2007dfcbd4 Mon Sep 17 00:00:00 2001
From: Tim Graham <timograham@gmail.com>
Date: Fri, 5 Jan 2018 15:49:54 -0500
Subject: [PATCH] Fixed #28882 -- Fixed cleaning of disabled MultiValueFields.

Thanks avalanchy for the initial patch.
---
 django/forms/fields.py                            |  4 ++++
 .../field_tests/test_multivaluefield.py           | 15 +++++++++++++++
 2 files changed, 19 insertions(+)

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):