mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-09 06:44:47 +03:00
Review step 1 - simplify to clarify
This commit is contained in:
parent
7971343a64
commit
24ba3b3743
|
@ -58,45 +58,22 @@ class APIException(Exception):
|
||||||
return self.detail
|
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
|
# The recommended style for using `ValidationError` is to keep it namespaced
|
||||||
# under `serializers`, in order to minimize potential confusion with Django's
|
# under `serializers`, in order to minimize potential confusion with Django's
|
||||||
# built in `ValidationError`. For example:
|
# built in `ValidationError`. For example:
|
||||||
#
|
#
|
||||||
# from rest_framework import serializers
|
# from rest_framework import serializers
|
||||||
# raise serializers.ValidationError('Value was invalid')
|
# 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):
|
class ValidationError(APIException):
|
||||||
status_code = status.HTTP_400_BAD_REQUEST
|
status_code = status.HTTP_400_BAD_REQUEST
|
||||||
|
|
||||||
def __init__(self, detail, code=None):
|
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.
|
# For validation errors the 'detail' key is always required.
|
||||||
# The details should always be coerced to a list if not already.
|
# The details should always be coerced to a list if not already.
|
||||||
if not isinstance(detail, dict) and not isinstance(detail, list):
|
if not isinstance(detail, dict) and not isinstance(detail, list):
|
||||||
detail = [detail]
|
detail = [detail]
|
||||||
self.detail = _force_text_recursive(detail)
|
self.detail = _force_text_recursive(detail)
|
||||||
|
self.code = code
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return six.text_type(self.detail)
|
return six.text_type(self.detail)
|
||||||
|
|
|
@ -32,7 +32,7 @@ from rest_framework.compat import (
|
||||||
unicode_to_repr
|
unicode_to_repr
|
||||||
)
|
)
|
||||||
from rest_framework.exceptions import (
|
from rest_framework.exceptions import (
|
||||||
ValidationError, build_error_from_django_validation_error
|
ValidationError
|
||||||
)
|
)
|
||||||
from rest_framework.settings import api_settings
|
from rest_framework.settings import api_settings
|
||||||
from rest_framework.utils import html, humanize_datetime, representation
|
from rest_framework.utils import html, humanize_datetime, representation
|
||||||
|
@ -505,9 +505,7 @@ class Field(object):
|
||||||
raise
|
raise
|
||||||
errors.extend(exc.detail)
|
errors.extend(exc.detail)
|
||||||
except DjangoValidationError as exc:
|
except DjangoValidationError as exc:
|
||||||
errors.extend(
|
errors.extend(exc.messages)
|
||||||
build_error_from_django_validation_error(exc)
|
|
||||||
)
|
|
||||||
if errors:
|
if errors:
|
||||||
raise ValidationError(errors)
|
raise ValidationError(errors)
|
||||||
|
|
||||||
|
|
|
@ -20,11 +20,9 @@ from django.db.models.fields import FieldDoesNotExist
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.translation import ugettext_lazy as _
|
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 DurationField as ModelDurationField
|
||||||
from rest_framework.compat import JSONField as ModelJSONField
|
from rest_framework.compat import JSONField as ModelJSONField
|
||||||
from rest_framework.compat import postgres_fields, unicode_to_repr
|
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 import model_meta
|
||||||
from rest_framework.utils.field_mapping import (
|
from rest_framework.utils.field_mapping import (
|
||||||
ClassLookupDict, get_field_kwargs, get_nested_relation_kwargs,
|
ClassLookupDict, get_field_kwargs, get_nested_relation_kwargs,
|
||||||
|
@ -221,6 +219,7 @@ class BaseSerializer(Field):
|
||||||
|
|
||||||
if self._errors and raise_exception:
|
if self._errors and raise_exception:
|
||||||
raise ValidationError(self.errors)
|
raise ValidationError(self.errors)
|
||||||
|
|
||||||
return not bool(self._errors)
|
return not bool(self._errors)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -301,8 +300,7 @@ def get_validation_error_detail(exc):
|
||||||
# exception class as well for simpler compat.
|
# exception class as well for simpler compat.
|
||||||
# Eg. Calling Model.clean() explicitly inside Serializer.validate()
|
# Eg. Calling Model.clean() explicitly inside Serializer.validate()
|
||||||
return {
|
return {
|
||||||
api_settings.NON_FIELD_ERRORS_KEY:
|
api_settings.NON_FIELD_ERRORS_KEY: list(exc.messages)
|
||||||
exceptions.build_error_from_django_validation_error(exc)
|
|
||||||
}
|
}
|
||||||
elif isinstance(exc.detail, dict):
|
elif isinstance(exc.detail, dict):
|
||||||
# If errors may be a dict we use the standard {key: list of values}.
|
# 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(
|
message = self.error_messages['invalid'].format(
|
||||||
datatype=type(data).__name__
|
datatype=type(data).__name__
|
||||||
)
|
)
|
||||||
error = ValidationErrorMessage(message, code='invalid')
|
|
||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
api_settings.NON_FIELD_ERRORS_KEY: [error]
|
api_settings.NON_FIELD_ERRORS_KEY: [message]
|
||||||
})
|
})
|
||||||
|
|
||||||
ret = OrderedDict()
|
ret = OrderedDict()
|
||||||
|
@ -443,9 +440,7 @@ class Serializer(BaseSerializer):
|
||||||
except ValidationError as exc:
|
except ValidationError as exc:
|
||||||
errors[field.field_name] = exc.detail
|
errors[field.field_name] = exc.detail
|
||||||
except DjangoValidationError as exc:
|
except DjangoValidationError as exc:
|
||||||
errors[field.field_name] = (
|
errors[field.field_name] = list(exc.messages)
|
||||||
exceptions.build_error_from_django_validation_error(exc)
|
|
||||||
)
|
|
||||||
except SkipField:
|
except SkipField:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
@ -580,18 +575,12 @@ class ListSerializer(BaseSerializer):
|
||||||
message = self.error_messages['not_a_list'].format(
|
message = self.error_messages['not_a_list'].format(
|
||||||
input_type=type(data).__name__
|
input_type=type(data).__name__
|
||||||
)
|
)
|
||||||
error = ValidationErrorMessage(
|
|
||||||
message,
|
|
||||||
code='not_a_list'
|
|
||||||
)
|
|
||||||
raise ValidationError({
|
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:
|
if not self.allow_empty and len(data) == 0:
|
||||||
message = ValidationErrorMessage(
|
message = self.error_messages['empty']
|
||||||
self.error_messages['empty'],
|
|
||||||
code='empty_not_allowed')
|
|
||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
api_settings.NON_FIELD_ERRORS_KEY: [message]
|
api_settings.NON_FIELD_ERRORS_KEY: [message]
|
||||||
})
|
})
|
||||||
|
|
|
@ -11,7 +11,7 @@ from __future__ import unicode_literals
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from rest_framework.compat import unicode_to_repr
|
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
|
from rest_framework.utils.representation import smart_repr
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,10 +101,7 @@ class UniqueTogetherValidator(object):
|
||||||
return
|
return
|
||||||
|
|
||||||
missing = {
|
missing = {
|
||||||
field_name: ValidationErrorMessage(
|
field_name: self.missing_message
|
||||||
self.missing_message,
|
|
||||||
code='required')
|
|
||||||
|
|
||||||
for field_name in self.fields
|
for field_name in self.fields
|
||||||
if field_name not in attrs
|
if field_name not in attrs
|
||||||
}
|
}
|
||||||
|
@ -190,9 +187,7 @@ class BaseUniqueForValidator(object):
|
||||||
'required' state on the fields they are applied to.
|
'required' state on the fields they are applied to.
|
||||||
"""
|
"""
|
||||||
missing = {
|
missing = {
|
||||||
field_name: ValidationErrorMessage(
|
field_name: self.missing_message
|
||||||
self.missing_message,
|
|
||||||
code='required')
|
|
||||||
for field_name in [self.field, self.date_field]
|
for field_name in [self.field, self.date_field]
|
||||||
if field_name not in attrs
|
if field_name not in attrs
|
||||||
}
|
}
|
||||||
|
@ -219,7 +214,7 @@ class BaseUniqueForValidator(object):
|
||||||
if queryset.exists():
|
if queryset.exists():
|
||||||
message = self.message.format(date_field=self.date_field)
|
message = self.message.format(date_field=self.date_field)
|
||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
self.field: ValidationErrorMessage(message, code='unique'),
|
self.field: message,
|
||||||
})
|
})
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user