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