Переписать обработчик ошибок валидации по умолчанию в django rest

Я использую django-rest для своего бэкенда и хочу переписать ошибки по умолчанию для полей. Мой текущий код выглядит следующим образом.

class DeckSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product

        fields = (
            "id",
            "title",
            "get_absolute_url",
            "description",
            "price",
            "image",
            "category_id",
            "category",
            "title"
        )
        extra_kwargs = {
            'title': {"error_messages": {"required": "Title cannot be empty"}},
            'image': {"error_messages": {"required": "Image cannot be empty"},}


        }

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

По умолчанию валидация сериализатора возвращает это значение, если поле отсутствует {title:"This field is required"}.

Есть ли способ перезаписать текущее сообщение, чтобы оно отображало непосредственно name_of_the_field + my_message. Пример {title: Title is required}

Я не ищу, как написать пользовательское сообщение об ошибке для одного поля, я ищу, как написать общие сообщения об ошибке для каждого поля, которое, например, отсутствует или равно null.

Мы можем достичь этого, написав пользовательский обработчик исключений.

Вот как может выглядеть пользовательский ответ:

{
    "status_code": 400,
    "type": "ValidationError",
    "message": "Bad request syntax or unsupported method",
    "errors": [
        "username: This field may not be null.",
        "email: This field may not be null.",
        "ticket number: This field may not be null."
    ]
}

Нам нужно создать файл: exception_handler.py в каталоге нашего проекта с кодом, который следует за ним; я использую utils для таких целей. Вы также можете поместить этот код куда угодно, но я предпочитаю иметь его в отдельном файле, предназначенном для этой цели.

from http import HTTPStatus

from rest_framework import exceptions
from rest_framework.views import Response, exception_handler


def api_exception_handler(exception: Exception, context: dict) -> Response:
    """Custom API exception handler."""

    # Call REST framework's default exception handler first,
    # to get the standard error response.
    response = exception_handler(exception, context)

    # Only alter the response when it's a validation error
    if not isinstance(exception, exceptions.ValidationError):
        return response

    # It's a validation error, there should be a Serializer
    view = context.get("view", None)
    serializer = view.get_serializer_class()()

    errors_list = []
    for key, details in response.data.items():

        if key in serializer.fields:
            label = serializer.fields[key].label
            help_text = serializer.fields[key].help_text

            for message in details:
                errors_list.append("{}: {}".format(label, message))

        elif key == "non_field_errors":
            for message in details:
                errors_list.append(message)

        else:
            for message in details:
                errors_list.append("{}: {}".format(key, message))

    # Using the description's of the HTTPStatus class as error message.
    http_code_to_message = {v.value: v.description for v in HTTPStatus}

    error_payload = {
        "status_code": 0,
        "type": "ValidationError",
        "message": "",
        "errors": [],
    }

    #  error = error_payload["error"]
    status_code = response.status_code

    error_payload["status_code"] = status_code
    error_payload["message"] = http_code_to_message[status_code]
    error_payload["errors"] = errors_list

    # Overwrite default exception_handler response data
    response.data = error_payload

    return response

Основная идея взята из отсюда, но я изменил ее под свои нужды. измените ее по своему усмотрению.

Не забудьте установить его в качестве обработчика исключений по умолчанию в вашем settings.py файле:

REST_FRAMEWORK["EXCEPTION_HANDLER"] = "utils.exception_handler.api_exception_handler";
Вернуться на верх