Как изменить ответ об ошибке в классе ModelViewSet, если детали не найдены для Django REST Framework? - PullRequest
1 голос
/ 12 февраля 2020

Я пытался реализовать этот ответ , чтобы создать собственный базовый Response класс для всех моих ModelViewSet классов. Моя проблема в функции retrieve. Если Id экземпляра, который я ищу, не найден, я не могу изменить Response с моим измененным response_format. Это все еще дает ответ по умолчанию. На что мне следует поменять свое условие if?
views.py:

class ResponseInfo(object):
    def __init__(self, **args):
        self.response = {
            "message": args.get('message', 'success'),
            "error": args.get('error', ),
            "data": args.get('data', []),
        }


class LanguageView(viewsets.ModelViewSet):
    def __init__(self, **kwargs):
        self.response_format = ResponseInfo().response
        super(LanguageView, self).__init__(**kwargs)

    permission_classes = [permissions.DjangoModelPermissions]
    queryset = Language.objects.all()
    serializer_class = LanguageSerializer

    def list(self, request, *args, **kwargs):
        # call the original 'list' to get the original response.
        response_data = super(LanguageView, self).list(request, *args, **kwargs)
        # customize the response data.
        self.response_format['data'] = response_data.data
        if not response_data.data:
            self.response_format['message'] = 'List is empty.'
            self.response_format['error'] = response_data.status_code
        return Response(self.response_format)

    def retrieve(self, request, *args, **kwargs):
        response_data = super(LanguageView, self).retrieve(request, *args, **kwargs)
        self.response_format['data'] = response_data.data
        if not response_data.data:
            self.response_format['message'] = 'Instance not found.'
            self.response_format['error'] = response_data.status_code
        return Response(self.response_format)

Ответ JSON при обнаружении экземпляра. Например, http://127.0.0.1: 8000 / languages ​​/ 1 / :

{
    "message": "success",
    "error": null,
    "data": {
        "id": 1,
        "name": "English",
        "icon": "http://127.0.0.1:8000/media/language_icons/English.png",
        "xml": "http://127.0.0.1:8000/media/-",
        "abbreviation": "En"
    }
}

Ответ JSON, когда экземпляр не найден. Например, URL: http://127.0.0.1: 8000 / languages ​​/ 4 / :

{
    "detail": "Not found."
}

Ответ, на который я надеюсь:

{  
    "message": "Instance not found.",  
    "error": "HTTP_404_NOT_FOUND",  
}

И возможно ли это не показывать переменную "error", когда нет ошибки? Для этого случая, когда список не пуст и найденный экземпляр найден.

1 Ответ

1 голос
/ 12 февраля 2020

Вы можете реализовать пользовательский обработчик исключений :

from rest_framework.views import exception_handler

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

    # Now add the HTTP status code to the response.
    if response is not None and response.status_code == 404:
        response.data = {  
            "message": "Instance not found.",  
            "error": "HTTP_404_NOT_FOUND",  
        }

    return response

Чтобы применить этот обработчик для вашего проекта, добавьте его в REST_FRAMEWORK настройки:

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'
}
...