django中的返回值可以分为:
- 异常返回值
- 正常返回值
1. Djanog中常见的异常返回值有如下
- 序列化校验错误
{ "age": [ "A valid integer is required." ] }
- 数据不存在
http://127.0.0.1:8000/api/demon/11/
{ "detail": "Not found." }
- 认证错误
{ "detail": "Incorrect authentication credentials." }
- 权限错误
{ "detail": "Authentication credentials were not provided." }
- 限流错误
{ "detail": "Request was throttled" }
- 其他错误:python的语法错误等
2.异常处理源码分析
上面的这些错误都会在dispath函数中进行捕获和处理
最后通过配置文件可以找到处理异常的函数
这个函数就是对常见的异常进行捕获处理,并且这个函数只能处理基于APIException的类,对于python法人语法错误是无法捕获的,只能继续上报,导致程序报错
3. 自定义异常处理方法
为此我们可以自定义该类如下
# encoding:utf-8 # author:kunmzhao # email:1102669474@qq.com from django.core.exceptions import PermissionDenied from django.http import Http404 from rest_framework import exceptions, status from rest_framework.response import Response from rest_framework.views import set_rollback from rest_framework.exceptions import AuthenticationFailed, NotAuthenticated, Throttled, ValidationError def exception_handler(exc, context): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django's built-in `Http404` and `PermissionDenied` exceptions. Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. """ if isinstance(exc, Http404): exc = exceptions.NotFound() exc.ret_code = 1001 elif isinstance(exc, PermissionDenied): exc = exceptions.PermissionDenied() exc.ret_code = 1002 elif isinstance(exc, (AuthenticationFailed, NotAuthenticated)): exc.ret_code = 1003 elif isinstance(exc, Throttled): exc.ret_code = 1004 elif isinstance(exc, ValidationError): exc.ret_code = 1005 headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['Retry-After'] = '%d' % exc.wait code = getattr(exc, "ret_code", -1) if isinstance(exc, exceptions.APIException): detail = exc.detail else: detail = "请求错误" print(detail) if isinstance(detail, (list, dict)): data = {"code": code, 'error': detail} else: data = {"code": code, 'error': detail} set_rollback() return Response(data, headers=headers)
配置如下
REST_FRAMEWORK = { 'EXCEPTION_HANDLER': 'utils.exception_handler', }
以后我们也可以自定义一些异常,放入该函数中,对异常进行分类,便于前端根据异常ma进行处理
4.正常返回值源码分析
我们可以重写该方法,返回我们需要的数据格式,如下
class DemonView(ModelViewSet): queryset = models.Student.objects.all() serializer_class = DemonDModelSerializers # authentication_classes = [DemonAuthentication, ] # permission_classes = [DemonPermission, ] # throttle_classes = [DemonThrottle, ] def finalize_response(self, request, response, *args, **kwargs): super().finalize_response(request, response, *args, **kwargs) if not response.exception: // 对于异常的response不做处理 response.data = {"code": 0, "data": response.data} return response
通过以上的方式就可以很好的自定义我们返回的数据格式了!!!