• drf之模块


    1.介绍

    安装 pip install djangorestframework

    注册:在INSTALLED_APPS列表中写:”rest_framework”

    drf框架的封装风格:

    import rest_framework
    from rest_framework.views import View                    #视图
    from rest_framework.response import Response    #响应
    from rest_framework.request import Request    #请求
    from rest_framework.serializers import Serializer    #序列化器
    from rest_framework.settings import APISettings    #设置
    from rest_framework.filters import SearchFilter    #过滤器
    from rest_framework.pagination import PageNumberPagination #分页
    from rest_framework.authentication import TokenAuthentication    #登陆
    from rest_framework.permissions import IsAuthenticated    #权限
    from rest_framework.throttling import SimpleRateThrottle    #频率

    drf请求生命周期:

    1)请求走的是APIViewas_view函数

    2)APIViewas_view调用父类Viewas_viewDjango原生的),还禁用了csrf认证

    3)在父类的as_view中分发dispatch方法走的又是APIViewdispatch

    4)完成任务分发,交给视图类的请求方法处理,得到请求的响应结果,返回给前台

    主要关注APIViewdispatch方法。

    dispatch源码分析:

    def dispatch(self, request, *args, **kwargs):
            """
            `.dispatch()` is pretty much the same as Django's regular dispatch,
            but with extra hooks for startup, finalize, and exception handling.
            """
            self.args = args
            self.kwargs = kwargs
            #请求模块(解析模块)
            request = self.initialize_request(request, *args, **kwargs)
            self.request = request
            self.headers = self.default_response_headers  # deprecate?
    
            try:
                #三大认证模块
                self.initial(request, *args, **kwargs)
    
                # Get the appropriate handler method
                if request.method.lower() in self.http_method_names:
                    handler = getattr(self, request.method.lower(),
                                      self.http_method_not_allowed)
                else:
                    handler = self.http_method_not_allowed
    #响应模块
                response = handler(request, *args, **kwargs)
    
            except Exception as exc:
    #异常模块
                response = self.handle_exception(exc)
    #渲染模块
            self.response = self.finalize_response(request, response, *args, **kwargs)
            return self.response

     

    2.请求模块:request对象

    源码入口:APIView类的dispatch方法中:request = self.initialize_request(request, *args, **kwargs)

    get请求的数据(拼接的参数)可以通过三个方法得到:

    request._request.GET        #二次封装

    request.GET #兼容

    request.query_params   #用这个   扩展

    post请求的数据(数据包)

    request._request.POST     

    request.POST

    request.data     #通过data拿数据,三种数据方式都能拿

    对于form-dataurlencoded,上面三种都能获取到数据。但是当前台提交的是json数据时,只有data能够获得,其他都是空。

    总结:

    drf对原生request做了二次封装,_request就是原生的request

    原生request对象的属性和方法都可以被drf_request对象直接访问;

    drf请求的所有拼接参数(get请求携带的参数)均被解析到query_params中,所有数据包数据(post请求在请求体中的数据)都被解析到data

    3.渲染模块

    有两种渲染方式:jsonbrowser浏览器。

    渲染模块源码入口:APIView类的dispatch方法中:self.response = self.finalize_response(request, response, *args, **kwargs)

    全局配置:

    settings.py配置文件中配置REST_FRAMEWORK,就全局配置所有接口的渲染方式(两种:方式1:就只是返回json字符串(比如通过postman),方式2:浏览器方式的数据:有响应信息和json数据)

    局部配置:

    自定义类中定义类属性(就不去父类中找了)

    from rest_framework.renderers import JSONRenderer

    render_classes = [JSONRenderer]   #必须是列表,因为要迭代

    模板渲染配置走的过程:自定义视图类--->继承APIView视图类--->自定义drf配置---->drf默认配置。

    全局配置就在自定义drf配置中改,具备就在自定义视图类中加类属性。

    4.解析模块

    url拼接参数:只有一种传参方式:拼接参数到url中(在url中)

    数据包参数:有3种:form-dataurlencodedjson

    解析模块源码入口:APIView类的dispatch方法中的 request = self.initialize_request(request, *args, **kwargs)

    解析配置也有两种:

    全局解析类、局部解析类

    全局配置:

    settings.py中的REST_FRAMEWORK字典中,写入

    'DEFAULT_PARSER_CLASSES': [
            'rest_framework.parsers.JSONParser',
            'rest_framework.parsers.FormParser',
            'rest_framework.parsers.MultiPartParser'
        ],      #三个都写上,那么3个都支持

    局部配置:

    在自定义类中写

    from rest_framework.parsers import JSONParser
    parser_classes = [JSONParser]    #写了这个这个类就只支持解析json格式提交的数据。

    5.异常处理模块

    异常模块源码入口:APIView类的dispatch方法中的response = self.handle_exception(exc)

    自定义异常:

    比如get取值取不到时,会出现query does not exist异常,显示在前台。

    1.settings.pyREST_FRAMEWORK字典中全局配置异常模块

    “EXECPTION_HANDLER” :”api.exception.exception_handler”

    get_exception_handler从默认的异常处理变为自己定义的异常处理函数

    自定义异常就是提供exception_handler异常处理函数,处理的目的就是让response一定有值。

    2.在应用下api新建一exceptions.py文件

    from rest_framework.views import exception_handler as drf_exception_handler

    form rest_framework.views import Response

    def exception_handler(exc, context):

      response = drf_exception_handler(exc, context)   #先交给默认的exception_handler处理

      if response is None:    #默认处理异常时当responseNone直接向前台展示,自定义就返回接口

        #if isinstance(exc, ‘’)   可以对exc的不同类型做判断,返回不同的异常

        return Response({

    “detail”: “服务器错误”

    })

      return response

    源码逻辑分析:

    首先源码入口为APIView类的dispatch方法中的response = self.handle_exception(exc)

    handle_exception里然后执行exception_handler = self.get_exception_handler(),从exception_handler 中获取response,如果response有值,就返回,没有值就报错给前台。get_exception_handler是从settings中获取exception_handler函数。exception_handler是处理异常的逻辑,要么返回response,要么返回None。可以在自定义exception_handler函数,然后再配置中指定自定义的异常函数,这样就会走自定义的。同时为了复用默认的异常处理,可以在自定义异常函数中先导入默认的,生成response,再针对response处理(比如是None,返回具体的错误)。

    总结:

    为什么要自定义异常模块?

    1)所有经过drfAPIView视图类产生的异常,都可以通过自定义异常提供异常处理方案(比如get默认就没有处理异常,就会在前台显示错误的细节)。

    2)drf默认提供了异常处理方案(在rest_framework.views.exception_handler中),单处理范围有限

    3)drf提供的处理方案有两种:处理了就返回处理信息,没处理就返回None(后续就是服务器抛异常给前台)。

    4)自定义异常的目的就是解决drf没有处理的异常,让前台得到合理的异常信息,后台记录异常具体信息。

     

    处理方案:

     修改配置文件

    REST_FRAMEWORK = {
     “EXECPTION_HANDLER” :”api.exception.exception_handler”
     }

    自定义exception_handler函数。

    1)先将异常处理交给rest_framework.viewsexception_handler做基础处理

    2)判断处理的结果(返回值)response,有值代表drf已经处理了,没值就要自己处理。自己处理,可以对exc进行异常判断,然后进行不同的处理。为空二次处理

     

    6.响应模块

    1)响应类构造器

    def __init__(self, data=None, status=None,
                template_name=None, header=None,
                exception=None, content_type=None):
            pass        

    data:响应数据

    statushttp响应状态码

    content_type:继承父类,默认是json,不用设置。

    其他不用了解。

    直接在自定义异常返回的Response中带上有名实参。

    return Response({
        “detail”: “服务器错误”
    }, status=500, exception=True)

    这个500可以从定义的变量中导入:from rest_framework import status

    status=status.HTTP_500_INTERNAL_SERVER_ERROR

     常规实例化响应对象:

    return Response(data={数据}, status=XXX, headers={设置的响应头})

     

  • 相关阅读:
    单细胞测序 RNA velocity | RNA速率
    单细胞测序的应用
    Centos7.4升级到Centos7.7
    K8S部署Redis Cluster集群(三主三从模式)
    K8S部署Nacos集群
    K8S部署Kafka界面管理工具(kafkamanager)
    K8S部署Kafka集群
    K8S部署RocketMQ集群(双主双从+同步模式)
    Android Studio/IDEA Gradle wrapper/tools/plugins config errors
    Android API Level对应Android版本一览表
  • 原文地址:https://www.cnblogs.com/yq055783/p/13149626.html
Copyright © 2020-2023  润新知