Коды проверки и сообщения в 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