django-rest-framework学习之路-9-自定义异常以及处理
作者:互联网
django-rest-framework学习之路-9-自定义异常以及处理
1、视图默认处理的异常
- 在REST framework内部产生的
APIException
的子类异常。 - 原生Django的
Http404
异常. - 原生Django的
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异常,则是这样子的
2、自定义异常
-
需要继承
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'
3、自定义异常处理函数
需要写一个函数,接收两个参数,第一个是需要处理的异常,第二个则是一个字典类型。
需要返回一个Response对象或者返回None,返回None则会向上报错,最终返回Django的HTTP 500的server error'响应。
例子
创建一个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中配置自定义处理函数
settings.py中配置文件函数路径
REST_FRAMEWORK = {
...
'EXCEPTION_HANDLER': 'tutorial.custom_exception_handler.custom_exception_handler'
}
目录结构
需要raise抛出异常
在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
运行后
4、一些内置的异常
ParseError
签名: ParseError(detail=None, code=None)
在访问request.data
时,如果请求中包含格式不正确的数据,则该异常会被抛出。
默认情况下该异常会返回HTTP状态码为"400 Bad Request"的响应。
AuthenticationFailed
签名: AuthenticationFailed(detail=None, code=None)
当请求包含错误的认证信息时抛出。
默认情况下该异常会返回HTTP状态码为"401 Unauthenticated"的响应,但也有可能返回状态码为"403 Forbidden"的响应,这个主要取决于当前使用的认证模式。查看authentication 文档以了解更多细节。
NotAuthenticated
签名: NotAuthenticated(detail=None, code=None)
当未带认证信息的请求检查权限出错时抛出。
默认情况下该异常会返回HTTP状态码为"401 Unauthenticated"的响应,但也有可能返回状态码为"403 Forbidden"的响应,这个主要取决于当前使用的认证模式。查看authentication 文档以了解更多细节。
PermissionDenied
签名: PermissionDenied(detail=None, code=None)
Raised when an authenticated request fails the permission checks.
当一个带认证信息的请求检查权限出错时抛出。
默认情况下该异常会返回HTTP状态码为"403 Forbidden"的响应。
NotFound
签名: NotFound(detail=None, code=None)
当给定URL的资源不存在的时候抛出。这个异常和Django标准的Http404
异常等同。
默认情况下该异常会返回HTTP状态码为"404 Not Found"的响应。
MethodNotAllowed
签名: MethodNotAllowed(method, detail=None, code=None)
当一个请求产生且没有view映射了该请求需要的对应方法来处理时抛出。
默认情况下该异常会返回HTTP状态码为"405 Method Not Allowed"的响应。
NotAcceptable
签名: NotAcceptable(detail=None, code=None)
当一个带有Accept
头的请求无法被任何当前可用的renderer满足时抛出。
默认情况下该异常会返回HTTP状态码为"406 Not Acceptable"的响应。
UnsupportedMediaType
签名: UnsupportedMediaType(media_type, detail=None, code=None)
当没有解析器能够在访问request.data
时处理其content type时抛出。
默认情况下该异常会返回HTTP状态码为"415 Unsupported Media Type"的响应。
Throttled
签名: Throttled(wait=None, detail=None, code=None)
当访问的请求无法通过throttling检查时抛出。
默认情况下该异常会返回HTTP状态码为"429 Too Many Requests"的响应。
标签:None,code,HTTP,自定义,detail,rest,django,异常,response 来源: https://www.cnblogs.com/rainbow-tan/p/16311001.html