【问题标题】:How to modify error response in ModelViewSet class if detail not found for Django REST Framework?如果找不到 Django REST Framework 的详细信息,如何修改 ModelViewSet 类中的错误响应?
【发布时间】:2020-02-12 05:22:22
【问题描述】:

我试图实现这个answer 来为我的所有ModelViewSet 类创建一个自定义基础Response 类。我的问题出在retrieve 函数上。如果找不到我正在寻找的实例的Id,我似乎无法用我修改的response_format 更改Response。它仍然给出默认响应。我应该将我的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 响应。例如网址:http://127.0.0.1:8000/languages/4/

{
    "detail": "Not found."
}

我希望得到的回应:

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

如果没有错误,是否可以不显示"error" 变量?对于这种情况,当列表不为空并找到搜索的实例时。

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    你可以实现custom exception handler:

    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'
    }
    

    【讨论】:

    • 像往常一样谢谢你,neverwalkaloneer!您的解决方案解决了我的两个问题。而且我认为我可以在custom_exception_handler 中为另一个HTTP 错误状态代码创建更多elif 条件。
    猜你喜欢
    • 2020-11-10
    • 2014-11-13
    • 1970-01-01
    • 2014-08-24
    • 2016-07-01
    • 2016-12-13
    • 2016-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多