Commit cdc25ac4 authored by Niclas Olofsson's avatar Niclas Olofsson Committed by Tim Graham
Browse files

Fixed #22808 -- Made ModelMultipleChoiceField validation more robust to invalid data types..

Thanks Mattias Lindvall for the report and inital patch.
parent 75790808
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -458,6 +458,7 @@ answer newbie questions, and generally made Django that much better:
    Todd O'Bryan <toddobryan@mac.com>
    Alex Ogier <alex.ogier@gmail.com>
    Joao Oliveira <joaoxsouls@gmail.com>
    Niclas Olofsson <n@niclasolofsson.se>
    Selwin Ong <selwin@ui.co.id>
    Gerardo Orozco <gerardo.orozco.mosqueda@gmail.com>
    Christian Oudard <christian.oudard@gmail.com>
+2 −2
Original line number Diff line number Diff line
@@ -1179,7 +1179,7 @@ class ModelChoiceField(ChoiceField):
        try:
            key = self.to_field_name or 'pk'
            value = self.queryset.get(**{key: value})
        except (ValueError, self.queryset.model.DoesNotExist):
        except (ValueError, TypeError, self.queryset.model.DoesNotExist):
            raise ValidationError(self.error_messages['invalid_choice'], code='invalid_choice')
        return value

@@ -1227,7 +1227,7 @@ class ModelMultipleChoiceField(ModelChoiceField):
        for pk in value:
            try:
                self.queryset.filter(**{key: pk})
            except ValueError:
            except (ValueError, TypeError):
                raise ValidationError(
                    self.error_messages['invalid_pk_value'],
                    code='invalid_pk_value',
+13 −0
Original line number Diff line number Diff line
@@ -1391,6 +1391,13 @@ class ModelChoiceFieldTests(TestCase):
            f.clean(None)
        with self.assertRaises(ValidationError):
            f.clean(0)

        # Invalid types that require TypeError to be caught (#22808).
        with self.assertRaises(ValidationError):
            f.clean([['fail']])
        with self.assertRaises(ValidationError):
            f.clean([{'foo': 'bar'}])

        self.assertEqual(f.clean(self.c2.id).name, "It's a test")
        self.assertEqual(f.clean(self.c3.id).name, 'Third')

@@ -1495,6 +1502,12 @@ class ModelMultipleChoiceFieldTests(TestCase):
        with self.assertRaises(ValidationError):
            f.clean(['fail'])

        # Invalid types that require TypeError to be caught (#22808).
        with self.assertRaises(ValidationError):
            f.clean([['fail']])
        with self.assertRaises(ValidationError):
            f.clean([{'foo': 'bar'}])

        # Add a Category object *after* the ModelMultipleChoiceField has already been
        # instantiated. This proves clean() checks the database during clean() rather
        # than caching it at time of instantiation.