django-rest-framework学习之路-9-自定义异常以及处理
APIException
的子类异常。Http404
异常.PermissionDenied
异常.以上的异常都会被处理,也就是说,如果你写一个异常,然后继承APIException
父类,然后通过raise抛出该异常,则这个异常信息就会被处理,当然,django自带的Http404
异常以及PermissionDenied
通过raise抛出,也是可以正常处理的。
例如:在views.py中直接抛出Http404异常
def create(self, request: Request, *args, **kwargs): raise Http404() return super().create(request, *args, **kwargs)
如果抛出PermissionDenied异常,则是这样子的
需要继承APIException
父类
需要在该类中设置.status_code
, .default_detail
以及default_code
属性。
例子:
创建tutorial/custom_exception.py文件且添加代码
from rest_framework.exceptions import APIException from rest_framework.status import HTTP_400_BAD_REQUEST class MyException(APIException): status_code = HTTP_400_BAD_REQUEST # 400状态码 default_detail = '这是自定义异常的default_detail' default_code = '这是自定义异常的default_code'
例子
创建一个tutorial/custom_exception_handler.py文件,填充下面的内容
from rest_framework.views import exception_handler def custom_exception_handler(exc, context): # 首先调用REST framework默认的异常处理, # 以获得标准的错误响应。 response = exception_handler(exc, context) print(f"type response:{type(response)}") print(f"response:{response}") print(f"response __dict__:{vars(response)}") print(f"type context:{type(context)}") print(f"context:{context}") # 接下来将HTTP状态码加到响应中。 if response is not None: response.data['status_code'] = response.status_code return response
settings.py中配置文件函数路径
REST_FRAMEWORK = { ... 'EXCEPTION_HANDLER': 'tutorial.custom_exception_handler.custom_exception_handler' }
目录结构
在snippets/views.py抛出异常
from django.contrib.auth.models import User from rest_framework import renderers, viewsets, permissions from rest_framework.decorators import action from rest_framework.request import Request from rest_framework.response import Response from snippets.models import Snippet from snippets.permissions import IsOwnerOrReadOnly from snippets.serializers import SnippetSerializer, UserSerializer from tutorial.custom_exception import MyException class UserViewSet(viewsets.ModelViewSet): """ 此视图自动提供`list`和`detail`操作。 """ queryset = User.objects.all() serializer_class = UserSerializer class SnippetViewSet(viewsets.ModelViewSet): """ 此视图自动提供`list`,`create`,`retrieve`,`update`和`destroy`操作。 另外我们还提供了一个额外的`highlight`操作。 """ queryset = Snippet.objects.all() serializer_class = SnippetSerializer permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly,) @action(detail=True, renderer_classes=[renderers.StaticHTMLRenderer]) def highlight(self, request, *args, **kwargs): snippet = self.get_object() return Response(snippet.highlighted) def perform_create(self, serializer): serializer.save() def create(self, request: Request, *args, **kwargs): raise MyException() return super().create(request, *args, **kwargs)
运行
备注:
处理函数的第一个参数是异常,它有下面的属性和方法可以用
exc.detail # 以文字形式返回报错的细节描述。
exc.get_codes() # 返回报错的标识码。
exc.get_full_details() # 返回报错的细节描述以及报错的标识码。
from rest_framework.views import exception_handler def custom_exception_handler(exc, context): # 首先调用REST framework默认的异常处理, # 以获得标准的错误响应。 response = exception_handler(exc, context) print(exc.detail) # 以文字形式返回报错的细节描述。 print(exc.get_codes()) # 返回报错的标识码。 print(exc.get_full_details()) # 返回报错的细节描述以及报错的标识码。 # 接下来将HTTP状态码加到响应中。 if response is not None: response.data['status_code'] = response.status_code return response
运行后
签名: ParseError(detail=None, code=None)
在访问request.data
时,如果请求中包含格式不正确的数据,则该异常会被抛出。
默认情况下该异常会返回HTTP状态码为"400 Bad Request"的响应。
签名: AuthenticationFailed(detail=None, code=None)
当请求包含错误的认证信息时抛出。
默认情况下该异常会返回HTTP状态码为"401 Unauthenticated"的响应,但也有可能返回状态码为"403 Forbidden"的响应,这个主要取决于当前使用的认证模式。查看authentication 文档以了解更多细节。
签名: NotAuthenticated(detail=None, code=None)
当未带认证信息的请求检查权限出错时抛出。
默认情况下该异常会返回HTTP状态码为"401 Unauthenticated"的响应,但也有可能返回状态码为"403 Forbidden"的响应,这个主要取决于当前使用的认证模式。查看authentication 文档以了解更多细节。
签名: PermissionDenied(detail=None, code=None)
Raised when an authenticated request fails the permission checks.
当一个带认证信息的请求检查权限出错时抛出。
默认情况下该异常会返回HTTP状态码为"403 Forbidden"的响应。
签名: NotFound(detail=None, code=None)
当给定URL的资源不存在的时候抛出。这个异常和Django标准的Http404
异常等同。
默认情况下该异常会返回HTTP状态码为"404 Not Found"的响应。
签名: MethodNotAllowed(method, detail=None, code=None)
当一个请求产生且没有view映射了该请求需要的对应方法来处理时抛出。
默认情况下该异常会返回HTTP状态码为"405 Method Not Allowed"的响应。
签名: NotAcceptable(detail=None, code=None)
当一个带有Accept
头的请求无法被任何当前可用的renderer满足时抛出。
默认情况下该异常会返回HTTP状态码为"406 Not Acceptable"的响应。
签名: UnsupportedMediaType(media_type, detail=None, code=None)
当没有解析器能够在访问request.data
时处理其content type时抛出。
默认情况下该异常会返回HTTP状态码为"415 Unsupported Media Type"的响应。
签名: Throttled(wait=None, detail=None, code=None)
当访问的请求无法通过throttling检查时抛出。
默认情况下该异常会返回HTTP状态码为"429 Too Many Requests"的响应。