diff --git a/rest_framework/exceptions.py b/rest_framework/exceptions.py index 7465415ea..7cee4468c 100644 --- a/rest_framework/exceptions.py +++ b/rest_framework/exceptions.py @@ -58,45 +58,22 @@ class APIException(Exception): return self.detail -def build_error_from_django_validation_error(exc_info): - code = getattr(exc_info, 'code', None) or 'invalid' - return [ - ValidationErrorMessage(msg, code=code) - for msg in exc_info.messages - ] - - # 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 ValidationErrorMessage(six.text_type): - code = None - - def __new__(cls, string, code=None, *args, **kwargs): - self = super(ValidationErrorMessage, cls).__new__( - cls, string, *args, **kwargs) - - self.code = code - return self - - class ValidationError(APIException): status_code = status.HTTP_400_BAD_REQUEST def __init__(self, detail, code=None): - # If code is there, this means we are dealing with a message. - if code and not isinstance(detail, ValidationErrorMessage): - detail = ValidationErrorMessage(detail, code=code) - # For validation errors the 'detail' key is always required. # The details should always be coerced to a list if not already. if not isinstance(detail, dict) and not isinstance(detail, list): detail = [detail] self.detail = _force_text_recursive(detail) + self.code = code def __str__(self): return six.text_type(self.detail) diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 2932de4fe..469c573f7 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -32,7 +32,7 @@ from rest_framework.compat import ( unicode_to_repr ) from rest_framework.exceptions import ( - ValidationError, build_error_from_django_validation_error + ValidationError ) from rest_framework.settings import api_settings from rest_framework.utils import html, humanize_datetime, representation @@ -505,9 +505,7 @@ class Field(object): raise errors.extend(exc.detail) except DjangoValidationError as exc: - errors.extend( - build_error_from_django_validation_error(exc) - ) + errors.extend(exc.messages) if errors: raise ValidationError(errors) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 79f80e30a..99d36a8a5 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -20,11 +20,9 @@ from django.db.models.fields import FieldDoesNotExist from django.utils.functional import cached_property from django.utils.translation import ugettext_lazy as _ -from rest_framework import exceptions from rest_framework.compat import DurationField as ModelDurationField from rest_framework.compat import JSONField as ModelJSONField from rest_framework.compat import postgres_fields, unicode_to_repr -from rest_framework.exceptions import ValidationErrorMessage from rest_framework.utils import model_meta from rest_framework.utils.field_mapping import ( ClassLookupDict, get_field_kwargs, get_nested_relation_kwargs, @@ -221,6 +219,7 @@ class BaseSerializer(Field): if self._errors and raise_exception: raise ValidationError(self.errors) + return not bool(self._errors) @property @@ -301,8 +300,7 @@ def get_validation_error_detail(exc): # exception class as well for simpler compat. # Eg. Calling Model.clean() explicitly inside Serializer.validate() return { - api_settings.NON_FIELD_ERRORS_KEY: - exceptions.build_error_from_django_validation_error(exc) + api_settings.NON_FIELD_ERRORS_KEY: list(exc.messages) } elif isinstance(exc.detail, dict): # If errors may be a dict we use the standard {key: list of values}. @@ -424,9 +422,8 @@ class Serializer(BaseSerializer): message = self.error_messages['invalid'].format( datatype=type(data).__name__ ) - error = ValidationErrorMessage(message, code='invalid') raise ValidationError({ - api_settings.NON_FIELD_ERRORS_KEY: [error] + api_settings.NON_FIELD_ERRORS_KEY: [message] }) ret = OrderedDict() @@ -443,9 +440,7 @@ class Serializer(BaseSerializer): except ValidationError as exc: errors[field.field_name] = exc.detail except DjangoValidationError as exc: - errors[field.field_name] = ( - exceptions.build_error_from_django_validation_error(exc) - ) + errors[field.field_name] = list(exc.messages) except SkipField: pass else: @@ -580,18 +575,12 @@ class ListSerializer(BaseSerializer): message = self.error_messages['not_a_list'].format( input_type=type(data).__name__ ) - error = ValidationErrorMessage( - message, - code='not_a_list' - ) raise ValidationError({ - api_settings.NON_FIELD_ERRORS_KEY: [error] + api_settings.NON_FIELD_ERRORS_KEY: [message] }) if not self.allow_empty and len(data) == 0: - message = ValidationErrorMessage( - self.error_messages['empty'], - code='empty_not_allowed') + message = self.error_messages['empty'] raise ValidationError({ api_settings.NON_FIELD_ERRORS_KEY: [message] }) diff --git a/rest_framework/validators.py b/rest_framework/validators.py index 11e986232..53d5479ce 100644 --- a/rest_framework/validators.py +++ b/rest_framework/validators.py @@ -11,7 +11,7 @@ from __future__ import unicode_literals from django.utils.translation import ugettext_lazy as _ from rest_framework.compat import unicode_to_repr -from rest_framework.exceptions import ValidationError, ValidationErrorMessage +from rest_framework.exceptions import ValidationError from rest_framework.utils.representation import smart_repr @@ -101,10 +101,7 @@ class UniqueTogetherValidator(object): return missing = { - field_name: ValidationErrorMessage( - self.missing_message, - code='required') - + field_name: self.missing_message for field_name in self.fields if field_name not in attrs } @@ -190,9 +187,7 @@ class BaseUniqueForValidator(object): 'required' state on the fields they are applied to. """ missing = { - field_name: ValidationErrorMessage( - self.missing_message, - code='required') + field_name: self.missing_message for field_name in [self.field, self.date_field] if field_name not in attrs } @@ -219,7 +214,7 @@ class BaseUniqueForValidator(object): if queryset.exists(): message = self.message.format(date_field=self.date_field) raise ValidationError({ - self.field: ValidationErrorMessage(message, code='unique'), + self.field: message, }) def __repr__(self):