diff options
Diffstat (limited to 'django/forms')
| -rw-r--r-- | django/forms/models.py | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/django/forms/models.py b/django/forms/models.py index 34ff3c478c..1ec1398147 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -1232,8 +1232,7 @@ class ModelMultipleChoiceField(ModelChoiceField): def to_python(self, value): if not value: return [] - to_py = super(ModelMultipleChoiceField, self).to_python - return [to_py(val) for val in value] + return list(self._check_values(value)) def clean(self, value): if self.required and not value: @@ -1242,7 +1241,29 @@ class ModelMultipleChoiceField(ModelChoiceField): return self.queryset.none() if not isinstance(value, (list, tuple)): raise ValidationError(self.error_messages['list'], code='list') + qs = self._check_values(value) + # Since this overrides the inherited ModelChoiceField.clean + # we run custom validators here + self.run_validators(value) + return qs + + def _check_values(self, value): + """ + Given a list of possible PK values, returns a QuerySet of the + corresponding objects. Raises a ValidationError if a given value is + invalid (not a valid PK, not in the queryset, etc.) + """ key = self.to_field_name or 'pk' + # deduplicate given values to avoid creating many querysets or + # requiring the database backend deduplicate efficiently. + try: + value = frozenset(value) + except TypeError: + # list of lists isn't hashable, for example + raise ValidationError( + self.error_messages['list'], + code='list', + ) for pk in value: try: self.queryset.filter(**{key: pk}) @@ -1261,9 +1282,6 @@ class ModelMultipleChoiceField(ModelChoiceField): code='invalid_choice', params={'value': val}, ) - # Since this overrides the inherited ModelChoiceField.clean - # we run custom validators here - self.run_validators(value) return qs def prepare_value(self, value): |
