From 2f9861d823620da7ecb291a8f005f53da12b1e89 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Mon, 31 Oct 2016 15:21:05 -0400 Subject: [PATCH] Fixed #27148 -- Fixed ModelMultipleChoiceField crash with invalid UUID. --- django/db/models/fields/__init__.py | 9 +++------ tests/model_fields/test_uuid.py | 8 ++++---- tests/model_forms/test_uuid.py | 6 ++++++ 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 4017c9088b..1ab2b6d313 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -2371,20 +2371,17 @@ class UUIDField(Field): if value is None: return None if not isinstance(value, uuid.UUID): - try: - value = uuid.UUID(value) - except AttributeError: - raise TypeError(self.error_messages['invalid'] % {'value': value}) + value = self.to_python(value) if connection.features.has_native_uuid_field: return value return value.hex def to_python(self, value): - if value and not isinstance(value, uuid.UUID): + if not isinstance(value, uuid.UUID): try: return uuid.UUID(value) - except ValueError: + except (AttributeError, ValueError): raise exceptions.ValidationError( self.error_messages['invalid'], code='invalid', diff --git a/tests/model_fields/test_uuid.py b/tests/model_fields/test_uuid.py index 1c173e526d..1e032ce9b0 100644 --- a/tests/model_fields/test_uuid.py +++ b/tests/model_fields/test_uuid.py @@ -40,17 +40,17 @@ class TestSaveLoad(TestCase): self.assertIsNone(loaded.field) def test_pk_validated(self): - with self.assertRaisesMessage(TypeError, 'is not a valid UUID'): + with self.assertRaisesMessage(exceptions.ValidationError, 'is not a valid UUID'): PrimaryKeyUUIDModel.objects.get(pk={}) - with self.assertRaisesMessage(TypeError, 'is not a valid UUID'): + with self.assertRaisesMessage(exceptions.ValidationError, 'is not a valid UUID'): PrimaryKeyUUIDModel.objects.get(pk=[]) def test_wrong_value(self): - with self.assertRaisesMessage(ValueError, 'badly formed hexadecimal UUID string'): + with self.assertRaisesMessage(exceptions.ValidationError, 'is not a valid UUID'): UUIDModel.objects.get(field='not-a-uuid') - with self.assertRaisesMessage(ValueError, 'badly formed hexadecimal UUID string'): + with self.assertRaisesMessage(exceptions.ValidationError, 'is not a valid UUID'): UUIDModel.objects.create(field='not-a-uuid') diff --git a/tests/model_forms/test_uuid.py b/tests/model_forms/test_uuid.py index 4dc7d511d7..b30da6d465 100644 --- a/tests/model_forms/test_uuid.py +++ b/tests/model_forms/test_uuid.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals from django import forms +from django.core.exceptions import ValidationError from django.test import TestCase from .models import UUIDPK @@ -27,3 +28,8 @@ class ModelFormBaseTest(TestCase): msg = "The UUIDPK could not be changed because the data didn't validate." with self.assertRaisesMessage(ValueError, msg): form.save() + + def test_model_multiple_choice_field_uuid_pk(self): + f = forms.ModelMultipleChoiceField(UUIDPK.objects.all()) + with self.assertRaisesMessage(ValidationError, "'invalid_uuid' is not a valid UUID."): + f.clean(['invalid_uuid'])