django DRF 组件 异常处理 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
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 | 校验失败 |
也就是说很多的没有在上面列出来的异常,就需要我们在自定义异常函数中自己处理了。
浙公网安备 33010602011771号