Коды проверки и сообщения в Django Rest Framework

используя поля из поля в сериализаторе, сообщения об ошибках проверки выглядят примерно так:

{
    "product": [
        "This field must be unique."
    ],
    "price": [
        "This field is required."
    ]
}

однако для API, который я пишу, я хотел бы предоставить уникальный код ошибки для каждой неудачной проверки, чтобы клиенты могли программно реагировать на ошибки проверки или могли предоставлять свои собственные пользовательские сообщения в пользовательском интерфейсе. В идеале ошибка json будет выглядеть примерно так:

{
    "product": [
        {
          "code": "unique",
          "message": "This field must be unique."
        }
    ],
    "price": [
        { 
          "code": "required",
          "message": "This field is required."
        }
    ]
}

текущий подход с использованием ValidationErrors делает это достаточно сложный. Просматривая код, кажется, что этот тип отчетов об ошибках в настоящее время не поддерживается. Однако я ищу подход для переопределения обработки ошибок в соответствии с этой моделью.

2 ответов


этот вопрос был опубликован довольно давно, поэтому я добавлю обновленный ответ. Новые версии DRF теперь поддерживают это, но все равно требуется немного пользовательского кода. Создание нового обработчика исключений с помощью do the trick:

from rest_framework.views import exception_handler
from rest_framework.exceptions import APIException


def full_details_exception_handler(exc, context):
    """
    This overrides the default exception handler to
    include the human-readable message AND the error code
    so that clients can respond programmatically.
    """
    if isinstance(exc, APIException):
        exc.detail = exc.get_full_details()

    return exception_handler(exc, context)

затем настройте DRF для использования этого пользовательского обработчика в настройках:

REST_FRAMEWORK['EXCEPTION_HANDLER'] = 'my_module.full_details_exception_handler'

было бы неплохо, если бы эта конфигурация была доступна в самом DRF, чтобы просто добавить ее в качестве опции конфигурации, но это довольно легкое решение чтобы включить коды ошибок.


добавить что-то вроде этого в свой сериализатор:

def is_valid(self, raise_exception=False):
    try:
        return super(ClientSerializer, self).is_valid(raise_exception)
    except exceptions.ValidationError as e:
        if 'email' in e.detail:
            for i in range(len(e.detail['email'])):
                if e.detail['email'][i] == UniqueValidator.message:
                    e.detail['email'][i] = {'code': 'not-unique'}
        raise e