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

 

 

通过以上的方式就可以很好的自定义我们返回的数据格式了!!!

posted on 2023-02-20 15:35  阿明明  阅读(172)  评论(0编辑  收藏  举报