django DRF 组件 异常处理 Exceptions

 

 

异常处理 Exceptions

REST framework本身在APIView提供了异常处理,但是仅针对drf内部现有的接口开发相关的异常进行格式处理,但是开发中我们还会使用到各种的数据或者进行各种网络请求,这些都有可能导致出现异常,这些异常在drf中是没有进行处理的,所以就会冒泡给django框架了,django框架会进行组织错误信息,作为html页面返回给客户端,所在在前后端分离项目中,可能js的ajax无法理解或者无法接收到这种数据,甚至导致js出现错误的情况。因此为了避免出现这种情况,我们可以自定义一个属于自己的异常处理函数,对于drf无法处理的异常,我们自己编写异常处理的代码逻辑。

针对于现有的drf的异常处理进行额外添加属于开发者自己的逻辑代码,一般我们编写的异常处理函数,会写一个公共的目录下或者主应用目录下。这里主应用下直接创建一个exceptions.py,代码:

 

from rest_framework.views import exception_handler, Response, status


def custom_exception_handler(exc, context):
    """
    自定义异常函数
    exc: 异常实例对象,发生异常时实例化出来的
    context: 字典,异常发生时python解释器会自动收集异常的执行上下文信息。
             所谓的执行上下文context就是python解释器在执行代码时保存在内存中的变量、函数、类、对象、模块、以及异常出现的路径,代码的行号等,等一系列的信息组成的环境信息。
    """
    # 1. 先让drf处理它能处理的异常
    response = exception_handler(exc, context)
    if response is None:
        """response的值为None,则表示当前异常无法drf处理"""
        if isinstance(exc, ZeroDivisionError):
            response = Response({"detail": "数学老师还有30秒达到战场,0不能作为除数!"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    return response

 

 

在配置文件中声明自定义的异常处理,settings.py,代码:

 

REST_FRAMEWORK = {
    # 异常配置
    'EXCEPTION_HANDLER': 'drfdemo.exceptions.custom_exception_handler',
}

 

 

视图代码:

class ErrorAPIView(APIView):
    def get(self, request):
        1/0
        return Response("ok")

 

urls.py,代码:

from django.urls import path, re_path
from . import views

urlpatterns = [
    path("auth/", views.AuthenticationAPIView.as_view()),
    path("pess/", views.PermissionAPIView.as_view({"get": "list", "post": "create"})),
    re_path("^pess/(?P<pk>\d+)/$", views.PermissionAPIView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
    path("throttle/", views.ThorttlingAPIView.as_view()),
    path("throttle2/", views.Thorttling2APIView.as_view()),
    path("list/", views.FilterAPIView.as_view()),
    path("order/", views.OrderAPIView.as_view()),
    path("stu/", views.StuListAPIView.as_view()),
    path("page/", views.PageAPIView.as_view()),
    path("err/", views.ErrorAPIView.as_view()),
]

 

 exceptions.py,代码:

from django.core.exceptions import ObjectDoesNotExist
from rest_framework.views import exception_handler, Response, status


def custom_exception_handler(exc, context):
    """
    自定义异常函数
    exc: 异常实例对象,发生异常时实例化出来的
    context: 字典,异常发生时python解释器会自动收集异常的执行上下文信息。
             所谓的执行上下文context就是python解释器在执行代码时保存在内存中的变量、函数、类、对象、模块、以及异常出现的路径,代码的行号等,等一系列的信息组成的环境信息。
    """
    # 1. 先让drf处理它能处理的异常
    response = exception_handler(exc, context)
    if response is None:
        """response的值为None,则表示当前异常无法drf处理"""
        if isinstance(exc, ZeroDivisionError):
            response = Response({"detail": "数学老师还有30秒达到战场,0不能作为除数!"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        if isinstance(exc, ObjectDoesNotExist):
            response = Response({"detail": "当前模型对象不存在!"}, status=status.HTTP_404_NOT_FOUND)

    return response

 

views.py

class ErrorAPIView(APIView):
    def get(self, request):
        # 1/0
        Student.objects.get(pk=1000)
        return Response("ok")

 

 

 

如果未声明自定义异常的话,drf会采用默认的方式,使用自己封装的异常处理函数,rest_framework/settings.py

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',  # from rest_framework.views import exception_handler
}

 

REST framework内置的异常类

异常类描述
APIException drf的所有异常的父类
ParseError 解析错误
AuthenticationFailed 认证失败
NotAuthenticated 尚未认证
PermissionDenied 权限拒绝
NotFound 404 未找到
MethodNotAllowed 请求方式不支持
NotAcceptable 要获取的数据格式不支持
UnsupportedMediaType 不支持的媒体格式
Throttled 超过限流次数
ValidationError 校验失败

也就是说很多的没有在上面列出来的异常,就需要我们在自定义异常函数中自己处理了。

 

 

 

posted @ 2025-06-24 15:07  minger_lcm  阅读(37)  评论(0)    收藏  举报