From ce8eb7ecce73391a5de099ecad7ce83a83fa74be Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 10 Oct 2016 20:30:45 +0100 Subject: [PATCH] Added 'get_codes' and 'get_full_details' --- rest_framework/exceptions.py | 27 ++++++++++++++++++++++++++- tests/test_validation_error.py | 12 ++---------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/rest_framework/exceptions.py b/rest_framework/exceptions.py index 956988325..f7c0048e8 100644 --- a/rest_framework/exceptions.py +++ b/rest_framework/exceptions.py @@ -20,7 +20,7 @@ from rest_framework.utils.serializer_helpers import ReturnDict, ReturnList def _get_error_details(data, default_code=None): """ Descend into a nested data structure, forcing any - lazy translation strings or strings into `ErrorMessage`. + lazy translation strings or strings into `ErrorDetail`. """ if isinstance(data, list): ret = [ @@ -43,6 +43,25 @@ def _get_error_details(data, default_code=None): return ErrorDetail(text, code) +def _get_codes(detail): + if isinstance(detail, list): + return [_get_codes(item) for item in detail] + elif isinstance(detail, dict): + return {key: _get_codes(value) for key, value in detail.items()} + return detail.code + + +def _get_full_details(detail): + if isinstance(detail, list): + 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 { + 'message': detail, + 'code': detail.code + } + + class ErrorDetail(six.text_type): """ A string-like object that can additionally @@ -99,6 +118,12 @@ class ValidationError(APIException): def __str__(self): return six.text_type(self.detail) + def get_codes(self): + return _get_codes(self.detail) + + def get_full_details(self): + return _get_full_details(self.detail) + class ParseError(APIException): status_code = status.HTTP_400_BAD_REQUEST diff --git a/tests/test_validation_error.py b/tests/test_validation_error.py index a9d244176..a59bb05f0 100644 --- a/tests/test_validation_error.py +++ b/tests/test_validation_error.py @@ -30,16 +30,8 @@ class TestValidationErrorWithCode(TestCase): self.DEFAULT_HANDLER = api_settings.EXCEPTION_HANDLER def exception_handler(exc, request): - return_errors = {} - for field_name, errors in exc.detail.items(): - return_errors[field_name] = [] - for error in errors: - return_errors[field_name].append({ - 'code': error.code, - 'message': error - }) - - return Response(return_errors, status=status.HTTP_400_BAD_REQUEST) + data = exc.get_full_details() + return Response(data, status=status.HTTP_400_BAD_REQUEST) api_settings.EXCEPTION_HANDLER = exception_handler