From 4b96e862b4674e85d1a28f2849685aa3135bc557 Mon Sep 17 00:00:00 2001 From: Grzegorz Slusarek Date: Mon, 8 Dec 2014 23:37:59 +0100 Subject: [PATCH] [1.7.x] Fixed #23674 -- Fixed a crash when a MultiValueField has invalid data. Backport of 0dea81cd6d34b3e41cc4bbec99b5fdf06142b09e from master --- django/forms/fields.py | 6 +++++- docs/releases/1.7.2.txt | 2 ++ tests/forms_tests/tests/test_forms.py | 16 ++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/django/forms/fields.py b/django/forms/fields.py index f686b34a09..2823aaf53a 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -1068,7 +1068,11 @@ class MultiValueField(Field): if not isinstance(initial, list): initial = self.widget.decompress(initial) for field, initial, data in zip(self.fields, initial, data): - if field._has_changed(field.to_python(initial), data): + try: + initial = field.to_python(initial) + except ValidationError: + return True + if field._has_changed(initial, data): return True return False diff --git a/docs/releases/1.7.2.txt b/docs/releases/1.7.2.txt index b049ae6837..ad2068044e 100644 --- a/docs/releases/1.7.2.txt +++ b/docs/releases/1.7.2.txt @@ -119,3 +119,5 @@ Bugfixes * Fixed bug in ``makemigrations`` that created broken migration files when dealing with multiple table inheritance and inheriting from more than one model (:ticket:`23956`). + +* Fixed a crash when a ``MultiValueField`` has invalid data (:ticket:`23674`). diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py index b79f53d6cb..6c13cf4177 100644 --- a/tests/forms_tests/tests/test_forms.py +++ b/tests/forms_tests/tests/test_forms.py @@ -1952,6 +1952,22 @@ class FormsTestCase(TestCase): self.assertFalse(id(field2.fields[0].choices) == id(field.fields[0].choices)) + def test_multivalue_initial_data(self): + """ + #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")) + super(DateAgeField, self).__init__(fields=fields, *args, **kwargs) + + class DateAgeForm(Form): + date_age = DateAgeField() + + data = {"date_age": ["1998-12-06", 16]} + form = DateAgeForm(data, initial={"date_age": ["200-10-10", 14]}) + self.assertTrue(form.has_changed()) + def test_multivalue_optional_subfields(self): class PhoneField(MultiValueField): def __init__(self, *args, **kwargs):