From c6e5878410ce7c1b26dd95c7ffb186dffba8acc2 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 30 Jul 2016 10:13:10 -0400 Subject: [PATCH] [1.10.x] Fixed #26970 -- Fixed crash with disabled ModelMultipleChoiceField. Backport of 4e861682904744b0ea3ead8552513c6f1a826c5a from master --- django/forms/models.py | 1 + tests/model_forms/tests.py | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/django/forms/models.py b/django/forms/models.py index 0738421d9e..15e251abe7 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -1250,6 +1250,7 @@ class ModelMultipleChoiceField(ModelChoiceField): return list(self._check_values(value)) def clean(self, value): + value = self.prepare_value(value) if self.required and not value: raise ValidationError(self.error_messages['required'], code='required') elif not self.required and not value: diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py index e18b19dcac..0b0390707e 100644 --- a/tests/model_forms/tests.py +++ b/tests/model_forms/tests.py @@ -1514,6 +1514,31 @@ class ModelChoiceFieldTests(TestCase): ['Select a valid choice. That choice is not one of the available choices.'] ) + def test_disabled_multiplemodelchoicefield(self): + class ArticleForm(forms.ModelForm): + categories = forms.ModelMultipleChoiceField(Category.objects.all(), required=False) + + class Meta: + model = Article + fields = ['categories'] + + category1 = Category.objects.create(name='cat1') + category2 = Category.objects.create(name='cat2') + article = Article.objects.create( + pub_date=datetime.date(1988, 1, 4), + writer=Writer.objects.create(name='Test writer'), + ) + article.categories.set([category1.pk]) + + form = ArticleForm(data={'categories': [category2.pk]}, instance=article) + self.assertEqual(form.errors, {}) + self.assertEqual([x.pk for x in form.cleaned_data['categories']], [category2.pk]) + # Disabled fields use the value from `instance` rather than `data`. + form = ArticleForm(data={'categories': [category2.pk]}, instance=article) + form.fields['categories'].disabled = True + self.assertEqual(form.errors, {}) + self.assertEqual([x.pk for x in form.cleaned_data['categories']], [category1.pk]) + class ModelMultipleChoiceFieldTests(TestCase): def setUp(self):