feat: Add some changes to ValidationError to support django style vadation errors (#8863)

This commit is contained in:
Ehsan200 2023-02-06 15:00:48 +03:30 committed by GitHub
parent 22d206c1e0
commit 4abfa28e08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 102 additions and 3 deletions

View File

@ -144,17 +144,30 @@ class ValidationError(APIException):
status_code = status.HTTP_400_BAD_REQUEST status_code = status.HTTP_400_BAD_REQUEST
default_detail = _('Invalid input.') default_detail = _('Invalid input.')
default_code = 'invalid' default_code = 'invalid'
default_params = {}
def __init__(self, detail=None, code=None): def __init__(self, detail=None, code=None, params=None):
if detail is None: if detail is None:
detail = self.default_detail detail = self.default_detail
if code is None: if code is None:
code = self.default_code code = self.default_code
if params is None:
params = self.default_params
# For validation failures, we may collect many errors together, # For validation failures, we may collect many errors together,
# so the details should always be coerced to a list if not already. # so the details should always be coerced to a list if not already.
if isinstance(detail, tuple): if isinstance(detail, str):
detail = list(detail) detail = [detail % params]
elif isinstance(detail, ValidationError):
detail = detail.detail
elif isinstance(detail, (list, tuple)):
final_detail = []
for detail_item in detail:
if isinstance(detail_item, ValidationError):
final_detail += detail_item.detail
else:
final_detail += [detail_item % params if isinstance(detail_item, str) else detail_item]
detail = final_detail
elif not isinstance(detail, dict) and not isinstance(detail, list): elif not isinstance(detail, dict) and not isinstance(detail, list):
detail = [detail] detail = [detail]

View File

@ -109,3 +109,89 @@ class TestValidationErrorConvertsTuplesToLists(TestCase):
assert len(error.detail) == 2 assert len(error.detail) == 2
assert str(error.detail[0]) == 'message1' assert str(error.detail[0]) == 'message1'
assert str(error.detail[1]) == 'message2' assert str(error.detail[1]) == 'message2'
class TestValidationErrorWithDjangoStyle(TestCase):
def test_validation_error_details(self):
error = ValidationError('Invalid value: %(value)s', params={'value': '42'})
assert str(error.detail[0]) == 'Invalid value: 42'
def test_validation_error_details_tuple(self):
error = ValidationError(
detail=('Invalid value: %(value1)s', 'Invalid value: %(value2)s'),
params={'value1': '42', 'value2': '43'},
)
assert isinstance(error.detail, list)
assert len(error.detail) == 2
assert str(error.detail[0]) == 'Invalid value: 42'
assert str(error.detail[1]) == 'Invalid value: 43'
def test_validation_error_details_list(self):
error = ValidationError(
detail=['Invalid value: %(value1)s', 'Invalid value: %(value2)s', ],
params={'value1': '42', 'value2': '43'}
)
assert isinstance(error.detail, list)
assert len(error.detail) == 2
assert str(error.detail[0]) == 'Invalid value: 42'
assert str(error.detail[1]) == 'Invalid value: 43'
def test_validation_error_details_validation_errors(self):
error = ValidationError(
detail=ValidationError(
detail='Invalid value: %(value1)s',
params={'value1': '42'},
),
)
assert isinstance(error.detail, list)
assert len(error.detail) == 1
assert str(error.detail[0]) == 'Invalid value: 42'
def test_validation_error_details_validation_errors_list(self):
error = ValidationError(
detail=[
ValidationError(
detail='Invalid value: %(value1)s',
params={'value1': '42'},
),
ValidationError(
detail='Invalid value: %(value2)s',
params={'value2': '43'},
),
'Invalid value: %(value3)s'
],
params={'value3': '44'}
)
assert isinstance(error.detail, list)
assert len(error.detail) == 3
assert str(error.detail[0]) == 'Invalid value: 42'
assert str(error.detail[1]) == 'Invalid value: 43'
assert str(error.detail[2]) == 'Invalid value: 44'
def test_validation_error_details_validation_errors_nested_list(self):
error = ValidationError(
detail=[
ValidationError(
detail='Invalid value: %(value1)s',
params={'value1': '42'},
),
ValidationError(
detail=[
'Invalid value: %(value2)s',
ValidationError(
detail='Invalid value: %(value3)s',
params={'value3': '44'},
)
],
params={'value2': '43'},
),
'Invalid value: %(value4)s'
],
params={'value4': '45'}
)
assert isinstance(error.detail, list)
assert len(error.detail) == 4
assert str(error.detail[0]) == 'Invalid value: 42'
assert str(error.detail[1]) == 'Invalid value: 43'
assert str(error.detail[2]) == 'Invalid value: 44'
assert str(error.detail[3]) == 'Invalid value: 45'