Commit 218abcc9 authored by Stephen Burrows's avatar Stephen Burrows Committed by Anssi Kääriäinen
Browse files

Fixed #14567 -- Made ModelMultipleChoiceField return EmptyQuerySet as empty value

parent d25a599d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1013,7 +1013,7 @@ class ModelMultipleChoiceField(ModelChoiceField):
        if self.required and not value:
            raise ValidationError(self.error_messages['required'])
        elif not self.required and not value:
            return []
            return self.queryset.none()
        if not isinstance(value, (list, tuple)):
            raise ValidationError(self.error_messages['list'])
        key = self.to_field_name or 'pk'
+6 −2
Original line number Diff line number Diff line
@@ -997,13 +997,17 @@ objects (in the case of ``ModelMultipleChoiceField``) into the
.. class:: ModelMultipleChoiceField(**kwargs)

    * Default widget: ``SelectMultiple``
    * Empty value: ``[]`` (an empty list)
    * Normalizes to: A list of model instances.
    * Empty value: An empty ``QuerySet`` (self.queryset.none())
    * Normalizes to: A ``QuerySet`` of model instances.
    * Validates that every id in the given list of values exists in the
      queryset.
    * Error message keys: ``required``, ``list``, ``invalid_choice``,
      ``invalid_pk_value``

    .. versionchanged:: 1.5
        The empty and normalized values were changed to be consistently
        ``QuerySets`` instead of ``[]`` and ``QuerySet`` respectively.

    Allows the selection of one or more model objects, suitable for
    representing a many-to-many relation. As with :class:`ModelChoiceField`,
    you can use ``label_from_instance`` to customize the object
+3 −0
Original line number Diff line number Diff line
@@ -422,6 +422,9 @@ on the form.
Miscellaneous
~~~~~~~~~~~~~

* :class:`django.forms.ModelMultipleChoiceField` now returns an empty
  ``QuerySet`` as the empty value instead of an empty list.

* :func:`~django.utils.http.int_to_base36` properly raises a :exc:`TypeError`
  instead of :exc:`ValueError` for non-integer inputs.

+3 −2
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ from django import forms
from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.validators import ValidationError
from django.db import connection
from django.db.models.query import EmptyQuerySet
from django.forms.models import model_to_dict
from django.utils.unittest import skipUnless
from django.test import TestCase
@@ -1035,8 +1036,8 @@ class OldFormForXTests(TestCase):
            f.clean([c6.id])

        f = forms.ModelMultipleChoiceField(Category.objects.all(), required=False)
        self.assertEqual(f.clean([]), [])
        self.assertEqual(f.clean(()), [])
        self.assertIsInstance(f.clean([]), EmptyQuerySet)
        self.assertIsInstance(f.clean(()), EmptyQuerySet)
        with self.assertRaises(ValidationError):
            f.clean(['10'])
        with self.assertRaises(ValidationError):
+6 −0
Original line number Diff line number Diff line
@@ -63,6 +63,12 @@ class ChoiceFieldModel(models.Model):
    multi_choice_int = models.ManyToManyField(ChoiceOptionModel, blank=False, related_name='multi_choice_int',
                                              default=lambda: [1])

class OptionalMultiChoiceModel(models.Model):
    multi_choice = models.ManyToManyField(ChoiceOptionModel, blank=False, related_name='not_relevant',
                                          default=lambda: ChoiceOptionModel.objects.filter(name='default'))
    multi_choice_optional = models.ManyToManyField(ChoiceOptionModel, blank=True, null=True,
                                                   related_name='not_relevant2')


class FileModel(models.Model):
    file = models.FileField(storage=temp_storage, upload_to='tests')
Loading