Use serializers.ValidationError

This commit is contained in:
Tom Christie 2014-10-17 13:23:14 +01:00
parent 5882a7a9d5
commit 05cbec9dd7
8 changed files with 120 additions and 107 deletions

View File

@ -144,11 +144,15 @@ The corresponding code would now look like this:
logging.info('Creating ticket "%s"' % name)
serializer.save(user=request.user) # Include the user when saving.
#### Use `rest_framework.exceptions.ValidationFailed`.
#### Using `serializers.ValidationError`.
Django's `ValidationError` class is intended for use with HTML forms and it's API makes its use slightly awkward with nested validation errors as can occur in serializers.
Previously `serializers.ValidationError` error was simply a synonym for `django.core.exceptions.ValidationError`. This has now been altered so that it inherits from the standard `APIException` base class.
We now include a simpler `ValidationFailed` exception class in REST framework that you should use when raising validation failures.
The reason behind this is that Django's `ValidationError` class is intended for use with HTML forms and its API makes using it slightly awkward with nested validation errors that can occur in serializers.
For most users this change shouldn't require any updates to your codebase, but it is worth ensuring that whenever raising validation errors you are always using the `serializers.ValidationError` exception class, and not Django's built-in exception.
We strongly recommend that you use the namespaced import style of `import serializers` and not `from serializers import ValidationError` in order to avoid any potential confusion.
#### Change to `validate_<field_name>`.
@ -156,14 +160,14 @@ The `validate_<field_name>` method hooks that can be attached to serializer clas
def validate_score(self, attrs, source):
if attrs[score] % 10 != 0:
raise ValidationError('This field should be a multiple of ten.')
raise serializers.ValidationError('This field should be a multiple of ten.')
return attrs
This is now simplified slightly, and the method hooks simply take the value to be validated, and return it's validated value.
def validate_score(self, value):
if value % 10 != 0:
raise ValidationError('This field should be a multiple of ten.')
raise serializers.ValidationError('This field should be a multiple of ten.')
return value
Any ad-hoc validation that applies to more than one field should go in the `.validate(self, attrs)` method as usual.

View File

@ -18,13 +18,13 @@ class AuthTokenSerializer(serializers.Serializer):
if user:
if not user.is_active:
msg = _('User account is disabled.')
raise exceptions.ValidationFailed(msg)
raise exceptions.ValidationError(msg)
else:
msg = _('Unable to log in with provided credentials.')
raise exceptions.ValidationFailed(msg)
raise exceptions.ValidationError(msg)
else:
msg = _('Must include "username" and "password"')
raise exceptions.ValidationFailed(msg)
raise exceptions.ValidationError(msg)
attrs['user'] = user
return attrs

View File

@ -24,7 +24,14 @@ class APIException(Exception):
return self.detail
class ValidationFailed(APIException):
# The recommended style for using `ValidationError` is to keep it namespaced
# under `serializers`, in order to minimize potential confusion with Django's
# built in `ValidationError`. For example:
#
# from rest_framework import serializers
# raise serializers.ValidationError('Value was invalid')
class ValidationError(APIException):
status_code = status.HTTP_400_BAD_REQUEST
def __init__(self, detail):

View File

@ -13,7 +13,7 @@ from rest_framework.compat import (
smart_text, EmailValidator, MinValueValidator, MaxValueValidator,
MinLengthValidator, MaxLengthValidator, URLValidator
)
from rest_framework.exceptions import ValidationFailed
from rest_framework.exceptions import ValidationError
from rest_framework.settings import api_settings
from rest_framework.utils import html, representation, humanize_datetime
import copy
@ -102,7 +102,7 @@ NOT_READ_ONLY_DEFAULT = 'May not set both `read_only` and `default`'
NOT_REQUIRED_DEFAULT = 'May not set both `required` and `default`'
USE_READONLYFIELD = 'Field(read_only=True) should be ReadOnlyField'
MISSING_ERROR_MESSAGE = (
'ValidationFailed raised by `{class_name}`, but error key `{key}` does '
'ValidationError raised by `{class_name}`, but error key `{key}` does '
'not exist in the `error_messages` dictionary.'
)
@ -264,7 +264,7 @@ class Field(object):
def run_validators(self, value):
"""
Test the given value against all the validators on the field,
and either raise a `ValidationFailed` or simply return.
and either raise a `ValidationError` or simply return.
"""
errors = []
for validator in self.validators:
@ -272,12 +272,12 @@ class Field(object):
validator.serializer_field = self
try:
validator(value)
except ValidationFailed as exc:
except ValidationError as exc:
errors.extend(exc.detail)
except DjangoValidationError as exc:
errors.extend(exc.messages)
if errors:
raise ValidationFailed(errors)
raise ValidationError(errors)
def validate(self, value):
pass
@ -305,7 +305,7 @@ class Field(object):
msg = MISSING_ERROR_MESSAGE.format(class_name=class_name, key=key)
raise AssertionError(msg)
message_string = msg.format(**kwargs)
raise ValidationFailed(message_string)
raise ValidationError(message_string)
@property
def root(self):

View File

@ -14,7 +14,7 @@ from django.core.exceptions import ImproperlyConfigured
from django.db import models
from django.utils import six
from django.utils.datastructures import SortedDict
from rest_framework.exceptions import ValidationFailed
from rest_framework.exceptions import ValidationError
from rest_framework.fields import empty, set_value, Field, SkipField
from rest_framework.settings import api_settings
from rest_framework.utils import html, model_meta, representation
@ -77,13 +77,6 @@ class BaseSerializer(Field):
raise NotImplementedError('`create()` must be implemented.')
def save(self, **kwargs):
assert not hasattr(self, 'restore_object'), (
'Serializer %s has old-style version 2 `.restore_object()` '
'that is no longer compatible with REST framework 3. '
'Use the new-style `.create()` and `.update()` methods instead.' %
self.__class__.__name__
)
validated_data = self.validated_data
if kwargs:
validated_data = dict(
@ -105,17 +98,24 @@ class BaseSerializer(Field):
return self.instance
def is_valid(self, raise_exception=False):
assert not hasattr(self, 'restore_object'), (
'Serializer %s has old-style version 2 `.restore_object()` '
'that is no longer compatible with REST framework 3. '
'Use the new-style `.create()` and `.update()` methods instead.' %
self.__class__.__name__
)
if not hasattr(self, '_validated_data'):
try:
self._validated_data = self.run_validation(self._initial_data)
except ValidationFailed as exc:
except ValidationError as exc:
self._validated_data = {}
self._errors = exc.detail
else:
self._errors = {}
if self._errors and raise_exception:
raise ValidationFailed(self._errors)
raise ValidationError(self._errors)
return not bool(self._errors)
@ -124,6 +124,8 @@ class BaseSerializer(Field):
if not hasattr(self, '_data'):
if self.instance is not None and not getattr(self, '_errors', None):
self._data = self.to_representation(self.instance)
elif hasattr(self, '_validated_data') and not getattr(self, '_errors', None):
self._data = self.to_representation(self.validated_data)
else:
self._data = self.get_initial()
return self._data
@ -329,7 +331,7 @@ class Serializer(BaseSerializer):
return None
if not isinstance(data, dict):
raise ValidationFailed({
raise ValidationError({
api_settings.NON_FIELD_ERRORS_KEY: ['Invalid data']
})
@ -338,8 +340,8 @@ class Serializer(BaseSerializer):
self.run_validators(value)
value = self.validate(value)
assert value is not None, '.validate() should return the validated data'
except ValidationFailed as exc:
raise ValidationFailed({
except ValidationError as exc:
raise ValidationError({
api_settings.NON_FIELD_ERRORS_KEY: exc.detail
})
return value
@ -359,7 +361,7 @@ class Serializer(BaseSerializer):
validated_value = field.run_validation(primitive_value)
if validate_method is not None:
validated_value = validate_method(validated_value)
except ValidationFailed as exc:
except ValidationError as exc:
errors[field.field_name] = exc.detail
except SkipField:
pass
@ -367,7 +369,7 @@ class Serializer(BaseSerializer):
set_value(ret, field.source_attrs, validated_value)
if errors:
raise ValidationFailed(errors)
raise ValidationError(errors)
return ret

View File

@ -1,6 +1,6 @@
from decimal import Decimal
from django.utils import timezone
from rest_framework import exceptions, fields, serializers
from rest_framework import serializers
import datetime
import django
import pytest
@ -17,8 +17,8 @@ class TestEmpty:
"""
By default a field must be included in the input.
"""
field = fields.IntegerField()
with pytest.raises(exceptions.ValidationFailed) as exc_info:
field = serializers.IntegerField()
with pytest.raises(serializers.ValidationError) as exc_info:
field.run_validation()
assert exc_info.value.detail == ['This field is required.']
@ -26,16 +26,16 @@ class TestEmpty:
"""
If `required=False` then a field may be omitted from the input.
"""
field = fields.IntegerField(required=False)
with pytest.raises(fields.SkipField):
field = serializers.IntegerField(required=False)
with pytest.raises(serializers.SkipField):
field.run_validation()
def test_disallow_null(self):
"""
By default `None` is not a valid input.
"""
field = fields.IntegerField()
with pytest.raises(exceptions.ValidationFailed) as exc_info:
field = serializers.IntegerField()
with pytest.raises(serializers.ValidationError) as exc_info:
field.run_validation(None)
assert exc_info.value.detail == ['This field may not be null.']
@ -43,7 +43,7 @@ class TestEmpty:
"""
If `allow_null=True` then `None` is a valid input.
"""
field = fields.IntegerField(allow_null=True)
field = serializers.IntegerField(allow_null=True)
output = field.run_validation(None)
assert output is None
@ -51,8 +51,8 @@ class TestEmpty:
"""
By default '' is not a valid input.
"""
field = fields.CharField()
with pytest.raises(exceptions.ValidationFailed) as exc_info:
field = serializers.CharField()
with pytest.raises(serializers.ValidationError) as exc_info:
field.run_validation('')
assert exc_info.value.detail == ['This field may not be blank.']
@ -60,7 +60,7 @@ class TestEmpty:
"""
If `allow_blank=True` then '' is a valid input.
"""
field = fields.CharField(allow_blank=True)
field = serializers.CharField(allow_blank=True)
output = field.run_validation('')
assert output is ''
@ -68,7 +68,7 @@ class TestEmpty:
"""
If `default` is set, then omitted values get the default input.
"""
field = fields.IntegerField(default=123)
field = serializers.IntegerField(default=123)
output = field.run_validation()
assert output is 123
@ -96,13 +96,13 @@ class TestSource:
class TestReadOnly:
def setup(self):
class TestSerializer(serializers.Serializer):
read_only = fields.ReadOnlyField()
writable = fields.IntegerField()
read_only = serializers.ReadOnlyField()
writable = serializers.IntegerField()
self.Serializer = TestSerializer
def test_validate_read_only(self):
"""
Read-only fields should not be included in validation.
Read-only serializers.should not be included in validation.
"""
data = {'read_only': 123, 'writable': 456}
serializer = self.Serializer(data=data)
@ -111,7 +111,7 @@ class TestReadOnly:
def test_serialize_read_only(self):
"""
Read-only fields should be serialized.
Read-only serializers.should be serialized.
"""
instance = {'read_only': 123, 'writable': 456}
serializer = self.Serializer(instance)
@ -121,13 +121,13 @@ class TestReadOnly:
class TestWriteOnly:
def setup(self):
class TestSerializer(serializers.Serializer):
write_only = fields.IntegerField(write_only=True)
readable = fields.IntegerField()
write_only = serializers.IntegerField(write_only=True)
readable = serializers.IntegerField()
self.Serializer = TestSerializer
def test_validate_write_only(self):
"""
Write-only fields should be included in validation.
Write-only serializers.should be included in validation.
"""
data = {'write_only': 123, 'readable': 456}
serializer = self.Serializer(data=data)
@ -136,7 +136,7 @@ class TestWriteOnly:
def test_serialize_write_only(self):
"""
Write-only fields should not be serialized.
Write-only serializers.should not be serialized.
"""
instance = {'write_only': 123, 'readable': 456}
serializer = self.Serializer(instance)
@ -146,8 +146,8 @@ class TestWriteOnly:
class TestInitial:
def setup(self):
class TestSerializer(serializers.Serializer):
initial_field = fields.IntegerField(initial=123)
blank_field = fields.IntegerField()
initial_field = serializers.IntegerField(initial=123)
blank_field = serializers.IntegerField()
self.serializer = TestSerializer()
def test_initial(self):
@ -163,7 +163,7 @@ class TestInitial:
class TestLabel:
def setup(self):
class TestSerializer(serializers.Serializer):
labeled = fields.IntegerField(label='My label')
labeled = serializers.IntegerField(label='My label')
self.serializer = TestSerializer()
def test_label(self):
@ -189,7 +189,7 @@ class TestInvalidErrorKey:
with pytest.raises(AssertionError) as exc_info:
self.field.to_native(123)
expected = (
'ValidationFailed raised by `ExampleField`, but error key '
'ValidationError raised by `ExampleField`, but error key '
'`incorrect` does not exist in the `error_messages` dictionary.'
)
assert str(exc_info.value) == expected
@ -198,7 +198,7 @@ class TestInvalidErrorKey:
class TestBooleanHTMLInput:
def setup(self):
class TestSerializer(serializers.Serializer):
archived = fields.BooleanField()
archived = serializers.BooleanField()
self.Serializer = TestSerializer
def test_empty_html_checkbox(self):
@ -243,7 +243,7 @@ class FieldValues:
Ensure that invalid values raise the expected validation error.
"""
for input_value, expected_failure in get_items(self.invalid_inputs):
with pytest.raises(exceptions.ValidationFailed) as exc_info:
with pytest.raises(serializers.ValidationError) as exc_info:
self.field.run_validation(input_value)
assert exc_info.value.detail == expected_failure
@ -283,7 +283,7 @@ class TestBooleanField(FieldValues):
False: False,
'other': True
}
field = fields.BooleanField()
field = serializers.BooleanField()
class TestNullBooleanField(FieldValues):
@ -310,7 +310,7 @@ class TestNullBooleanField(FieldValues):
None: None,
'other': True
}
field = fields.NullBooleanField()
field = serializers.NullBooleanField()
# String types...
@ -330,7 +330,7 @@ class TestCharField(FieldValues):
1: '1',
'abc': 'abc'
}
field = fields.CharField()
field = serializers.CharField()
class TestEmailField(FieldValues):
@ -345,7 +345,7 @@ class TestEmailField(FieldValues):
'examplecom': ['Enter a valid email address.']
}
outputs = {}
field = fields.EmailField()
field = serializers.EmailField()
class TestRegexField(FieldValues):
@ -359,7 +359,7 @@ class TestRegexField(FieldValues):
'A9': ["This value does not match the required pattern."]
}
outputs = {}
field = fields.RegexField(regex='[a-z][0-9]')
field = serializers.RegexField(regex='[a-z][0-9]')
class TestSlugField(FieldValues):
@ -373,7 +373,7 @@ class TestSlugField(FieldValues):
'slug 99': ["Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."]
}
outputs = {}
field = fields.SlugField()
field = serializers.SlugField()
class TestURLField(FieldValues):
@ -387,7 +387,7 @@ class TestURLField(FieldValues):
'example.com': ['Enter a valid URL.']
}
outputs = {}
field = fields.URLField()
field = serializers.URLField()
# Number types...
@ -415,7 +415,7 @@ class TestIntegerField(FieldValues):
1.0: 1,
0.0: 0
}
field = fields.IntegerField()
field = serializers.IntegerField()
class TestMinMaxIntegerField(FieldValues):
@ -435,7 +435,7 @@ class TestMinMaxIntegerField(FieldValues):
'4': ['Ensure this value is less than or equal to 3.'],
}
outputs = {}
field = fields.IntegerField(min_value=1, max_value=3)
field = serializers.IntegerField(min_value=1, max_value=3)
class TestFloatField(FieldValues):
@ -461,7 +461,7 @@ class TestFloatField(FieldValues):
1.0: 1.0,
0.0: 0.0,
}
field = fields.FloatField()
field = serializers.FloatField()
class TestMinMaxFloatField(FieldValues):
@ -483,7 +483,7 @@ class TestMinMaxFloatField(FieldValues):
'3.1': ['Ensure this value is less than or equal to 3.'],
}
outputs = {}
field = fields.FloatField(min_value=1, max_value=3)
field = serializers.FloatField(min_value=1, max_value=3)
class TestDecimalField(FieldValues):
@ -518,7 +518,7 @@ class TestDecimalField(FieldValues):
Decimal('1.09'): '1.1',
Decimal('0.04'): '0.0'
}
field = fields.DecimalField(max_digits=3, decimal_places=1)
field = serializers.DecimalField(max_digits=3, decimal_places=1)
class TestMinMaxDecimalField(FieldValues):
@ -534,7 +534,7 @@ class TestMinMaxDecimalField(FieldValues):
'20.1': ['Ensure this value is less than or equal to 20.'],
}
outputs = {}
field = fields.DecimalField(
field = serializers.DecimalField(
max_digits=3, decimal_places=1,
min_value=10, max_value=20
)
@ -554,13 +554,13 @@ class TestNoStringCoercionDecimalField(FieldValues):
Decimal('1.09'): Decimal('1.1'),
Decimal('0.04'): Decimal('0.0'),
}
field = fields.DecimalField(
field = serializers.DecimalField(
max_digits=3, decimal_places=1,
coerce_to_string=False
)
# Date & time fields...
# Date & time serializers...
class TestDateField(FieldValues):
"""
@ -578,7 +578,7 @@ class TestDateField(FieldValues):
outputs = {
datetime.date(2001, 1, 1): '2001-01-01'
}
field = fields.DateField()
field = serializers.DateField()
class TestCustomInputFormatDateField(FieldValues):
@ -592,7 +592,7 @@ class TestCustomInputFormatDateField(FieldValues):
'2001-01-01': ['Date has wrong format. Use one of these formats instead: DD [Jan-Dec] YYYY']
}
outputs = {}
field = fields.DateField(input_formats=['%d %b %Y'])
field = serializers.DateField(input_formats=['%d %b %Y'])
class TestCustomOutputFormatDateField(FieldValues):
@ -604,7 +604,7 @@ class TestCustomOutputFormatDateField(FieldValues):
outputs = {
datetime.date(2001, 1, 1): '01 Jan 2001'
}
field = fields.DateField(format='%d %b %Y')
field = serializers.DateField(format='%d %b %Y')
class TestNoOutputFormatDateField(FieldValues):
@ -616,7 +616,7 @@ class TestNoOutputFormatDateField(FieldValues):
outputs = {
datetime.date(2001, 1, 1): datetime.date(2001, 1, 1)
}
field = fields.DateField(format=None)
field = serializers.DateField(format=None)
class TestDateTimeField(FieldValues):
@ -641,7 +641,7 @@ class TestDateTimeField(FieldValues):
datetime.datetime(2001, 1, 1, 13, 00): '2001-01-01T13:00:00',
datetime.datetime(2001, 1, 1, 13, 00, tzinfo=timezone.UTC()): '2001-01-01T13:00:00Z'
}
field = fields.DateTimeField(default_timezone=timezone.UTC())
field = serializers.DateTimeField(default_timezone=timezone.UTC())
class TestCustomInputFormatDateTimeField(FieldValues):
@ -655,7 +655,7 @@ class TestCustomInputFormatDateTimeField(FieldValues):
'2001-01-01T20:50': ['Datetime has wrong format. Use one of these formats instead: hh:mm[AM|PM], DD [Jan-Dec] YYYY']
}
outputs = {}
field = fields.DateTimeField(default_timezone=timezone.UTC(), input_formats=['%I:%M%p, %d %b %Y'])
field = serializers.DateTimeField(default_timezone=timezone.UTC(), input_formats=['%I:%M%p, %d %b %Y'])
class TestCustomOutputFormatDateTimeField(FieldValues):
@ -667,7 +667,7 @@ class TestCustomOutputFormatDateTimeField(FieldValues):
outputs = {
datetime.datetime(2001, 1, 1, 13, 00): '01:00PM, 01 Jan 2001',
}
field = fields.DateTimeField(format='%I:%M%p, %d %b %Y')
field = serializers.DateTimeField(format='%I:%M%p, %d %b %Y')
class TestNoOutputFormatDateTimeField(FieldValues):
@ -679,7 +679,7 @@ class TestNoOutputFormatDateTimeField(FieldValues):
outputs = {
datetime.datetime(2001, 1, 1, 13, 00): datetime.datetime(2001, 1, 1, 13, 00),
}
field = fields.DateTimeField(format=None)
field = serializers.DateTimeField(format=None)
class TestNaiveDateTimeField(FieldValues):
@ -692,7 +692,7 @@ class TestNaiveDateTimeField(FieldValues):
}
invalid_inputs = {}
outputs = {}
field = fields.DateTimeField(default_timezone=None)
field = serializers.DateTimeField(default_timezone=None)
class TestTimeField(FieldValues):
@ -710,7 +710,7 @@ class TestTimeField(FieldValues):
outputs = {
datetime.time(13, 00): '13:00:00'
}
field = fields.TimeField()
field = serializers.TimeField()
class TestCustomInputFormatTimeField(FieldValues):
@ -724,7 +724,7 @@ class TestCustomInputFormatTimeField(FieldValues):
'13:00': ['Time has wrong format. Use one of these formats instead: hh:mm[AM|PM]'],
}
outputs = {}
field = fields.TimeField(input_formats=['%I:%M%p'])
field = serializers.TimeField(input_formats=['%I:%M%p'])
class TestCustomOutputFormatTimeField(FieldValues):
@ -736,7 +736,7 @@ class TestCustomOutputFormatTimeField(FieldValues):
outputs = {
datetime.time(13, 00): '01:00PM'
}
field = fields.TimeField(format='%I:%M%p')
field = serializers.TimeField(format='%I:%M%p')
class TestNoOutputFormatTimeField(FieldValues):
@ -748,7 +748,7 @@ class TestNoOutputFormatTimeField(FieldValues):
outputs = {
datetime.time(13, 00): datetime.time(13, 00)
}
field = fields.TimeField(format=None)
field = serializers.TimeField(format=None)
# Choice types...
@ -768,7 +768,7 @@ class TestChoiceField(FieldValues):
outputs = {
'good': 'good'
}
field = fields.ChoiceField(
field = serializers.ChoiceField(
choices=[
('poor', 'Poor quality'),
('medium', 'Medium quality'),
@ -794,7 +794,7 @@ class TestChoiceFieldWithType(FieldValues):
'1': 1,
1: 1
}
field = fields.ChoiceField(
field = serializers.ChoiceField(
choices=[
(1, 'Poor quality'),
(2, 'Medium quality'),
@ -819,7 +819,7 @@ class TestChoiceFieldWithListChoices(FieldValues):
outputs = {
'good': 'good'
}
field = fields.ChoiceField(choices=('poor', 'medium', 'good'))
field = serializers.ChoiceField(choices=('poor', 'medium', 'good'))
class TestMultipleChoiceField(FieldValues):
@ -838,7 +838,7 @@ class TestMultipleChoiceField(FieldValues):
outputs = [
(['aircon', 'manual'], set(['aircon', 'manual']))
]
field = fields.MultipleChoiceField(
field = serializers.MultipleChoiceField(
choices=[
('aircon', 'AirCon'),
('manual', 'Manual drive'),
@ -847,7 +847,7 @@ class TestMultipleChoiceField(FieldValues):
)
# File fields...
# File serializers...
class MockFile:
def __init__(self, name='', size=0, url=''):
@ -881,7 +881,7 @@ class TestFileField(FieldValues):
(MockFile(name='example.txt', url='/example.txt'), '/example.txt'),
('', None)
]
field = fields.FileField(max_length=10)
field = serializers.FileField(max_length=10)
class TestFieldFieldWithName(FieldValues):
@ -893,14 +893,14 @@ class TestFieldFieldWithName(FieldValues):
outputs = [
(MockFile(name='example.txt', url='/example.txt'), 'example.txt')
]
field = fields.FileField(use_url=False)
field = serializers.FileField(use_url=False)
# Stub out mock Django `forms.ImageField` class so we don't *actually*
# call into it's regular validation, or require PIL for testing.
class FailImageValidation(object):
def to_python(self, value):
raise exceptions.ValidationFailed(self.error_messages['invalid_image'])
raise serializers.ValidationError(self.error_messages['invalid_image'])
class PassImageValidation(object):
@ -917,7 +917,7 @@ class TestInvalidImageField(FieldValues):
(MockFile(name='example.txt', size=10), ['Upload a valid image. The file you uploaded was either not an image or a corrupted image.'])
]
outputs = {}
field = fields.ImageField(_DjangoImageField=FailImageValidation)
field = serializers.ImageField(_DjangoImageField=FailImageValidation)
class TestValidImageField(FieldValues):
@ -929,10 +929,10 @@ class TestValidImageField(FieldValues):
]
invalid_inputs = {}
outputs = {}
field = fields.ImageField(_DjangoImageField=PassImageValidation)
field = serializers.ImageField(_DjangoImageField=PassImageValidation)
# Composite fields...
# Composite serializers...
class TestListField(FieldValues):
"""
@ -950,7 +950,7 @@ class TestListField(FieldValues):
([1, 2, 3], [1, 2, 3]),
(['1', '2', '3'], [1, 2, 3])
]
field = fields.ListField(child=fields.IntegerField())
field = serializers.ListField(child=serializers.IntegerField())
# Tests for FieldField.
@ -963,7 +963,7 @@ class MockRequest:
class TestFileFieldContext:
def test_fully_qualified_when_request_in_context(self):
field = fields.FileField(max_length=10)
field = serializers.FileField(max_length=10)
field._context = {'request': MockRequest()}
obj = MockFile(name='example.txt', url='/example.txt')
value = field.to_representation(obj)

View File

@ -1,6 +1,6 @@
from .utils import mock_reverse, fail_reverse, BadType, MockObject, MockQueryset
from django.core.exceptions import ImproperlyConfigured
from rest_framework import exceptions, serializers
from rest_framework import serializers
from rest_framework.test import APISimpleTestCase
import pytest
@ -30,13 +30,13 @@ class TestPrimaryKeyRelatedField(APISimpleTestCase):
assert instance is self.instance
def test_pk_related_lookup_does_not_exist(self):
with pytest.raises(exceptions.ValidationFailed) as excinfo:
with pytest.raises(serializers.ValidationError) as excinfo:
self.field.to_internal_value(4)
msg = excinfo.value.detail[0]
assert msg == "Invalid pk '4' - object does not exist."
def test_pk_related_lookup_invalid_type(self):
with pytest.raises(exceptions.ValidationFailed) as excinfo:
with pytest.raises(serializers.ValidationError) as excinfo:
self.field.to_internal_value(BadType())
msg = excinfo.value.detail[0]
assert msg == 'Incorrect type. Expected pk value, received BadType.'
@ -120,13 +120,13 @@ class TestSlugRelatedField(APISimpleTestCase):
assert instance is self.instance
def test_slug_related_lookup_does_not_exist(self):
with pytest.raises(exceptions.ValidationFailed) as excinfo:
with pytest.raises(serializers.ValidationError) as excinfo:
self.field.to_internal_value('doesnotexist')
msg = excinfo.value.detail[0]
assert msg == 'Object with name=doesnotexist does not exist.'
def test_slug_related_lookup_invalid_type(self):
with pytest.raises(exceptions.ValidationFailed) as excinfo:
with pytest.raises(serializers.ValidationError) as excinfo:
self.field.to_internal_value(BadType())
msg = excinfo.value.detail[0]
assert msg == 'Invalid value.'

View File

@ -2,7 +2,7 @@ from __future__ import unicode_literals
from django.core.validators import MaxValueValidator
from django.db import models
from django.test import TestCase
from rest_framework import exceptions, generics, serializers, status
from rest_framework import generics, serializers, status
from rest_framework.test import APIRequestFactory
factory = APIRequestFactory()
@ -37,7 +37,7 @@ class ShouldValidateModelSerializer(serializers.ModelSerializer):
def validate_renamed(self, value):
if len(value) < 3:
raise exceptions.ValidationFailed('Minimum 3 characters.')
raise serializers.ValidationError('Minimum 3 characters.')
return value
class Meta:
@ -73,10 +73,10 @@ class ValidationSerializer(serializers.Serializer):
foo = serializers.CharField()
def validate_foo(self, attrs, source):
raise exceptions.ValidationFailed("foo invalid")
raise serializers.ValidationError("foo invalid")
def validate(self, attrs):
raise exceptions.ValidationFailed("serializer invalid")
raise serializers.ValidationError("serializer invalid")
class TestAvoidValidation(TestCase):
@ -158,7 +158,7 @@ class TestChoiceFieldChoicesValidate(TestCase):
value = self.CHOICES[0][0]
try:
f.to_internal_value(value)
except exceptions.ValidationFailed:
except serializers.ValidationError:
self.fail("Value %s does not validate" % str(value))
# def test_nested_choices(self):