Django休息框架自定义404错误页面

时间:2015-02-06 13:42:22

标签: django django-rest-framework

如何自定义Django休息框架错误页面。找不到它。在我的休息动作代码中:

from django.http import Http404

class SomeAction(APIView):
    def get(self, *args, **kwargs):
        raise Http404()

我需要在prod中显示自定义错误页面。

2 个答案:

答案 0 :(得分:2)

from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.template import loader, RequestContext, Context
from apps.settings import DEBUG
from libs.requestprovider.middleware import get_current_request

from rest_framework.views import exception_handler



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

    # Now add the HTTP status code to the response.
    if response is not None:
        response.data['status_code'] = response.status_code

    if not DEBUG:
        #errors can be more generic
        if response.data['status_code'] == 404:
            t = loader.get_template('404.html')
            c = RequestContext(get_current_request(), {})
            return HttpResponse(t.render(c), content_type="text/html")
    return response

答案 1 :(得分:1)

TL; DR

class YourAPIView(APIView):
    @staticmethod
    def my_exception_handler(exc, context):
        response = exception_handler(exc, context)
        if if response.status_code >= 400:
            return HttpResponse(loader.get_template('your.html').render(context), content_type='text/html')
        return response

    def get_exception_handler(self):
        return self.my_exception_handler

长话

此链接(custom-exception-handling)告诉您将EXCEPTION_HANDLER设置为您的链接,您会注意到默认设置为rest_framework.views.exception_handler

当然,您可以按照tutorial进行操作,但是如果您不想使用全局设置进行控制,请参阅以下内容。

我建议您在函数(rest_framework.views.exception_handler)上设置断点以查看发生了什么,然后您将了解所有过程。

如果您不想调试,我会在下面列出要点。

# rest_framework\views.py

class APIView(View):
    ...

    def dispatch(self, request, *args, **kwargs):
        ...
        try:
            ...
        except Exception as exc:
            response = self.handle_exception(exc)  # <-- focus here
        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response
    
     def handle_exception(self, exc):
        ...
        exception_handler = self.get_exception_handler()  # <-- focus here
    
        context = self.get_exception_handler_context()
        response = exception_handler(exc, context)
        ...
        return response
    
    def get_exception_handler(self):
        return self.settings.EXCEPTION_HANDLER

从以上代码中,您知道可以更改get_exception_handler,然后全部更改!

这是一个示例:

# views.py

from rest_framework import generics
from django.http import HttpResponse
from rest_framework import status
from django.template import loader
from rest_framework.views import exception_handler


class YourAPIView(generics.ListAPIView):
    ...
    def get(self, request, *args, **kwargs):
        return HttpResponse('ok', content_type='text/html')

    @staticmethod
    def my_exception_handler(exc, context):
        response = exception_handler(exc, context)  # <-- this is the default exception_handler
        if response.status_code in (status.HTTP_400_BAD_REQUEST, status.HTTP_401_UNAUTHORIZED, status.HTTP_403_FORBIDDEN):
            my_400_and_403_template = loader.get_template('error.html')  #  settings.py -> TEMPLATES = [{'DIRS': [ str(Path(BASE_DIR)/Path('templates/your_custom_dir')).replace('\\', '/') ]}]  # Where your_custom_dir should contain error.html
            return HttpResponse(my_400_and_403_template.render(context), content_type='text/html')
        return response

    def get_exception_handler(self):
        return self.my_exception_handler

    # def handle_exception(self, exc):
    #    return super().handle_exception(exc)