diff --git a/django/forms/models.py b/django/forms/models.py index 5c2c77cbf2..2d068eba1e 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -1175,6 +1175,12 @@ class ModelMultipleChoiceField(ModelChoiceField): msg = _('Hold down "Control", or "Command" on a Mac, to select more than one.') self.help_text = string_concat(self.help_text, ' ', msg) + def to_python(self, value): + if not value: + return [] + to_py = super(ModelMultipleChoiceField, self).to_python + return [to_py(val) for val in value] + def clean(self, value): if self.required and not value: raise ValidationError(self.error_messages['required'], code='required') diff --git a/docs/releases/1.6.1.txt b/docs/releases/1.6.1.txt index 5eeb446b88..2ac8822c9c 100644 --- a/docs/releases/1.6.1.txt +++ b/docs/releases/1.6.1.txt @@ -22,6 +22,9 @@ Bug fixes raised an error (#21439). * Fixed a regression that prevented editable ``GenericRelation`` subclasses from working in ``ModelForms``. +* Added missing ``to_python`` method for ``ModelMultipleChoiceField`` which + is required in Django 1.6 to properly detect changes from initial values + (#21568). * Fixed ``django.contrib.humanize`` translations where the unicode sequence for the non-breaking space was returned verbatim (#21415). * Fixed :djadmin:`loaddata` error when fixture file name contained any dots diff --git a/tests/model_forms_regress/tests.py b/tests/model_forms_regress/tests.py index 963c7e552d..d6c05f3153 100644 --- a/tests/model_forms_regress/tests.py +++ b/tests/model_forms_regress/tests.py @@ -45,6 +45,29 @@ class ModelMultipleChoiceFieldTests(TestCase): f.clean([p.pk for p in Person.objects.all()[8:9]]) self.assertTrue(self._validator_run) + def test_model_multiple_choice_show_hidden_initial(self): + """ + Test support of show_hidden_initial by ModelMultipleChoiceField. + """ + class PersonForm(forms.Form): + persons = forms.ModelMultipleChoiceField(show_hidden_initial=True, + queryset=Person.objects.all()) + + person1 = Person.objects.create(name="Person 1") + person2 = Person.objects.create(name="Person 2") + + form = PersonForm(initial={'persons': [person1, person2]}, + data={'initial-persons': [str(person1.pk), str(person2.pk)], + 'persons': [str(person1.pk), str(person2.pk)]}) + self.assertTrue(form.is_valid()) + self.assertFalse(form.has_changed()) + + form = PersonForm(initial={'persons': [person1, person2]}, + data={'initial-persons': [str(person1.pk), str(person2.pk)], + 'persons': [str(person2.pk)]}) + self.assertTrue(form.is_valid()) + self.assertTrue(form.has_changed()) + class TripleForm(forms.ModelForm): class Meta: