mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-27 16:40:03 +03:00
Adding params to error details
This commit is contained in:
parent
7f3a3557a0
commit
d1b8511f91
|
@ -38,7 +38,8 @@ def _get_error_details(data, default_code=None):
|
||||||
|
|
||||||
text = force_str(data)
|
text = force_str(data)
|
||||||
code = getattr(data, 'code', default_code)
|
code = getattr(data, 'code', default_code)
|
||||||
return ErrorDetail(text, code)
|
params = getattr(data, 'params', tuple())
|
||||||
|
return ErrorDetail(text, code, params)
|
||||||
|
|
||||||
|
|
||||||
def _get_codes(detail):
|
def _get_codes(detail):
|
||||||
|
@ -54,10 +55,16 @@ def _get_full_details(detail):
|
||||||
return [_get_full_details(item) for item in detail]
|
return [_get_full_details(item) for item in detail]
|
||||||
elif isinstance(detail, dict):
|
elif isinstance(detail, dict):
|
||||||
return {key: _get_full_details(value) for key, value in detail.items()}
|
return {key: _get_full_details(value) for key, value in detail.items()}
|
||||||
return {
|
|
||||||
|
_base = {
|
||||||
'message': detail,
|
'message': detail,
|
||||||
'code': detail.code
|
'code': detail.code
|
||||||
}
|
}
|
||||||
|
params = getattr(detail, "params", None)
|
||||||
|
|
||||||
|
if params:
|
||||||
|
_base.update({"params": params})
|
||||||
|
return _base
|
||||||
|
|
||||||
|
|
||||||
class ErrorDetail(str):
|
class ErrorDetail(str):
|
||||||
|
@ -65,10 +72,12 @@ class ErrorDetail(str):
|
||||||
A string-like object that can additionally have a code.
|
A string-like object that can additionally have a code.
|
||||||
"""
|
"""
|
||||||
code = None
|
code = None
|
||||||
|
params = None
|
||||||
|
|
||||||
def __new__(cls, string, code=None):
|
def __new__(cls, string, code=None, params=None):
|
||||||
self = super().__new__(cls, string)
|
self = super().__new__(cls, string)
|
||||||
self.code = code
|
self.code = code
|
||||||
|
self.params = params
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
|
@ -82,11 +91,13 @@ class ErrorDetail(str):
|
||||||
return not self.__eq__(other)
|
return not self.__eq__(other)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'ErrorDetail(string=%r, code=%r)' % (
|
base = 'ErrorDetail(string=%r, code=%r' % (
|
||||||
str(self),
|
str(self),
|
||||||
self.code,
|
self.code,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return base + ', params=%r)' % self.params if self.params else base + ')'
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash(str(self))
|
return hash(str(self))
|
||||||
|
|
||||||
|
@ -105,7 +116,6 @@ class APIException(Exception):
|
||||||
detail = self.default_detail
|
detail = self.default_detail
|
||||||
if code is None:
|
if code is None:
|
||||||
code = self.default_code
|
code = self.default_code
|
||||||
|
|
||||||
self.detail = _get_error_details(detail, code)
|
self.detail = _get_error_details(detail, code)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -141,6 +151,7 @@ class ValidationError(APIException):
|
||||||
default_code = 'invalid'
|
default_code = 'invalid'
|
||||||
|
|
||||||
def __init__(self, detail=None, code=None):
|
def __init__(self, detail=None, code=None):
|
||||||
|
print(detail, code)
|
||||||
if detail is None:
|
if detail is None:
|
||||||
detail = self.default_detail
|
detail = self.default_detail
|
||||||
if code is None:
|
if code is None:
|
||||||
|
|
|
@ -236,12 +236,14 @@ def get_error_detail(exc_info):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return [
|
return [
|
||||||
ErrorDetail((error.message % error.params) if error.params else error.message,
|
ErrorDetail((error.message % error.params) if error.params else error.message,
|
||||||
code=error.code if error.code else code)
|
code=error.code if error.code else code,
|
||||||
|
params=error.params)
|
||||||
for error in exc_info.error_list]
|
for error in exc_info.error_list]
|
||||||
return {
|
return {
|
||||||
k: [
|
k: [
|
||||||
ErrorDetail((error.message % error.params) if error.params else error.message,
|
ErrorDetail((error.message % error.params) if error.params else error.message,
|
||||||
code=error.code if error.code else code)
|
code=error.code if error.code else code,
|
||||||
|
params=error.params)
|
||||||
for error in errors
|
for error in errors
|
||||||
] for k, errors in error_dict.items()
|
] for k, errors in error_dict.items()
|
||||||
}
|
}
|
||||||
|
@ -599,6 +601,7 @@ class Field:
|
||||||
raise
|
raise
|
||||||
errors.extend(exc.detail)
|
errors.extend(exc.detail)
|
||||||
except DjangoValidationError as exc:
|
except DjangoValidationError as exc:
|
||||||
|
print("YOOOOOOOOOO", exc, exc.code, exc.params)
|
||||||
errors.extend(get_error_detail(exc))
|
errors.extend(get_error_detail(exc))
|
||||||
if errors:
|
if errors:
|
||||||
raise ValidationError(errors)
|
raise ValidationError(errors)
|
||||||
|
|
|
@ -12,17 +12,17 @@ factory = APIRequestFactory()
|
||||||
|
|
||||||
class ExampleSerializer(serializers.Serializer):
|
class ExampleSerializer(serializers.Serializer):
|
||||||
char = serializers.CharField()
|
char = serializers.CharField()
|
||||||
integer = serializers.IntegerField()
|
integer = serializers.IntegerField(min_value=1, required=False)
|
||||||
|
|
||||||
|
|
||||||
class ErrorView(APIView):
|
class ErrorView(APIView):
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
ExampleSerializer(data={}).is_valid(raise_exception=True)
|
ExampleSerializer(data={"integer": 0}).is_valid(raise_exception=True)
|
||||||
|
|
||||||
|
|
||||||
@api_view(['GET'])
|
@api_view(['GET'])
|
||||||
def error_view(request):
|
def error_view(request):
|
||||||
ExampleSerializer(data={}).is_valid(raise_exception=True)
|
ExampleSerializer(data={"integer": 0}).is_valid(raise_exception=True)
|
||||||
|
|
||||||
|
|
||||||
class TestValidationErrorWithFullDetails(TestCase):
|
class TestValidationErrorWithFullDetails(TestCase):
|
||||||
|
@ -41,8 +41,13 @@ class TestValidationErrorWithFullDetails(TestCase):
|
||||||
'code': 'required',
|
'code': 'required',
|
||||||
}],
|
}],
|
||||||
'integer': [{
|
'integer': [{
|
||||||
'message': 'This field is required.',
|
'message': 'Ensure this value is greater than or equal to 1.',
|
||||||
'code': 'required'
|
'code': 'min_value',
|
||||||
|
'params': {
|
||||||
|
'limit_value': 1,
|
||||||
|
'show_value': 0,
|
||||||
|
'value': 0
|
||||||
|
}
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +83,7 @@ class TestValidationErrorWithCodes(TestCase):
|
||||||
|
|
||||||
self.expected_response_data = {
|
self.expected_response_data = {
|
||||||
'char': ['required'],
|
'char': ['required'],
|
||||||
'integer': ['required'],
|
'integer': ['min_value'],
|
||||||
}
|
}
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user