Я не хочу, чтобы ответ drf ValidationError был текстовым. Как это сделать? - PullRequest
2 голосов
/ 15 октября 2019

Я использую django rest framework. Как изменить детализацию DRF ValidationError, чтобы она не была текстовой? Например:

raise  ValidationError(detail={"something": True})

ответ:

{
    "something": "True"
}

ожидаемый ответ:

{
    "something": true
}

1 Ответ

2 голосов
/ 15 октября 2019

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)

Как вы видите, вызывается функция _get_error_details(detail, code) для манипулирования вашими деталями:

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)

Здесь ваш логический тип становится строкой (text = force_text(data) часть). Один из способов преодолеть это - переписать класс ValidationError с self.detail = detail вместо self.detail = _get_error_details(detail, code). Хотя я бы не советовал делать это и просто придерживаться поведения по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...