I'm using django rest framework. How do I change the DRF ValidationError
detail not to be textual?
For example:
raise ValidationError(detail={"something": True})
response:
{
"something": "True"
}
expected response:
{
"something": true
}
In rest_framework/exceptions.py
:
class ValidationError(APIException):
status_code = status.HTTP_400_BAD_REQUEST
default_detail = _('Invalid input.')
default_code = 'invalid'
def __init__(self, detail=None, code=None):
if detail is None:
detail = self.default_detail
if code is None:
code = self.default_code
# For validation failures, we may collect many errors together,
# so the details should always be coerced to a list if not already.
if not isinstance(detail, dict) and not isinstance(detail, list):
detail = [detail]
self.detail = _get_error_details(detail, code)
As you can see function _get_error_details(detail, code)
gets called to manipulate your detail:
def _get_error_details(data, default_code=None):
"""
Descend into a nested data structure, forcing any
lazy translation strings or strings into `ErrorDetail`.
"""
if isinstance(data, list):
ret = [
_get_error_details(item, default_code) for item in data
]
if isinstance(data, ReturnList):
return ReturnList(ret, serializer=data.serializer)
return ret
elif isinstance(data, dict):
ret = {
key: _get_error_details(value, default_code)
for key, value in data.items()
}
if isinstance(data, ReturnDict):
return ReturnDict(ret, serializer=data.serializer)
import pdb
pdb.set_trace()
return ret
text = force_text(data)
code = getattr(data, 'code', default_code)
return ErrorDetail(text, code)
This is where your boolean becomes string (text = force_text(data)
part).
One way to overcome this is to overwrite the ValidationError
class with self.detail = detail
instead of self.detail = _get_error_details(detail, code)
. Although I wouldnt suggest doing this and just sticking with the default behaviour.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With