aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/topics/3.0-announcement.md14
-rw-r--r--rest_framework/authtoken/serializers.py6
-rw-r--r--rest_framework/exceptions.py9
-rw-r--r--rest_framework/fields.py12
-rw-r--r--rest_framework/serializers.py32
-rw-r--r--tests/test_fields.py134
-rw-r--r--tests/test_relations.py10
-rw-r--r--tests/test_validation.py10
8 files changed, 120 insertions, 107 deletions
diff --git a/docs/topics/3.0-announcement.md b/docs/topics/3.0-announcement.md
index f868b344..658b50d3 100644
--- a/docs/topics/3.0-announcement.md
+++ b/docs/topics/3.0-announcement.md
@@ -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.
diff --git a/rest_framework/authtoken/serializers.py b/rest_framework/authtoken/serializers.py
index a808d0a3..f31dded1 100644
--- a/rest_framework/authtoken/serializers.py
+++ b/rest_framework/authtoken/serializers.py
@@ -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
diff --git a/rest_framework/exceptions.py b/rest_framework/exceptions.py
index b7c2d16d..388d3dee 100644
--- a/rest_framework/exceptions.py
+++ b/rest_framework/exceptions.py
@@ -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):
diff --git a/rest_framework/fields.py b/rest_framework/fields.py
index 597d5e12..2da4aa8b 100644
--- a/rest_framework/fields.py
+++ b/rest_framework/fields.py
@@ -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):
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index 30e6bfeb..d29dc684 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -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
diff --git a/tests/test_fields.py b/tests/test_fields.py
index 5e8c67c5..6dc5f87d 100644
--- a/tests/test_fields.py
+++ b/tests/test_fields.py
@@ -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)
diff --git a/tests/test_relations.py b/tests/test_relations.py
index 53c1b25c..16ead1f2 100644
--- a/tests/test_relations.py
+++ b/tests/test_relations.py
@@ -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.'
diff --git a/tests/test_validation.py b/tests/test_validation.py
index 849c7e9d..4d64e6e1 100644
--- a/tests/test_validation.py
+++ b/tests/test_validation.py
@@ -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):