django中APIView里的dispatch和as_view方法分析

位置:

from rest_framework.views import APIView

继承APIView类视图形式的路由:

path('booksapiview/', views.BooksAPIView.as_view()),  #在这个地方应该写个函数内存地址

继承APIView类的视图函数:

from rest_framework.views import APIView

class BooksAPIView(APIView):
    def get(self):
        pass
    
    def post(self):
        pass

APIView源码分析:

继承了APIView的视图函数,最终执行的是APIView里的as_view方法

@classmethod
def as_view(cls, **initkwargs):
    """
    Store the original class on the view function.

    This allows us to discover information about the view when we do URL
    reverse lookups.  Used for breadcrumb generation.
    """
    if isinstance(getattr(cls, 'queryset', None), models.query.QuerySet):
        def force_evaluation():
            raise RuntimeError(
                'Do not evaluate the `.queryset` attribute directly, '
                'as the result will be cached and reused between requests. '
                'Use `.all()` or call `.get_queryset()` instead.'
            )

        cls.queryset._fetch_all = force_evaluation

    # 1.调用APIView父类,也就是View类中的as_view方法,将其返回值view在赋值给view
    view = super().as_view(**initkwargs)
    # 2.这里践行了一切皆对象的原则,将cls这个视图类给了view.cls,下面哪个也是一样
    view.cls = cls
    view.initkwargs = initkwargs

    # Note: session based authentication is explicitly CSRF validated,
    # all other authentication is CSRF exempt.
    # 3.这句话的意思就是以后所有继承APIView的试图函数都没有csrf认证了,和View类一样,APIview类的as_view方法最后也返回了view
    # 只不过apiview新增了去除csrf认证这里
    return csrf_exempt(view)

注意:上述返回的view内存地址,需要去找dispatch方法是先去apiview里找,而不是view类中的dispatch了

apiview里的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这个方法返回的新的由rest_framework中的Request类实例化产生的request对象
    request = self.initialize_request(request, *args, **kwargs)
    # 又把新的request对象给了视图函数中的request,从此,视图函数中的request就是新的request对象了
    self.request = request
    self.headers = self.default_response_headers  # deprecate?

    try:
        # 这里执行了apiview里的initial方法,这个方法里面包含了三大认证模块(重要)
        self.initial(request, *args, **kwargs)

        # Get the appropriate handler method
        # 三大认证过了之后,继续走,这里和view里面差不多,通过反射得到对应请求方式的函数地址
        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

        # 将get请求或者其他请求方式执行之后的结果在给response模块
        response = handler(request, *args, **kwargs)

    # 这里是三大认证出异常的异常模块
    except Exception as exc:
        response = self.handle_exception(exc)

    # 渲染模块,对response这个相应结果在进行包装(就是在前端看到的由rest_framework渲染出来的数据结果页面)
    self.response = self.finalize_response(request, response, *args, **kwargs)
    # 返回该渲染模块
    return self.response

def initial(self, request, *args, **kwargs):
    # 该方法最重要的就是下面三句代码
    # Ensure that the incoming request is permitted
    # 这个是认证组件
    self.perform_authentication(request)
    # 这个是权限组件
    self.check_permissions(request)
    # 这个是频率组件
    self.check_throttles(request)

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:django中APIView里的dispatch和as_view方法分析 - Python技术站

(0)
上一篇 2023年4月2日 下午4:39
下一篇 2023年4月2日 下午4:39

相关文章

  • 线程

    1. 什么是线程 线程就是进程里面的执行单位,每一个进程肯定都自带一个线程,真正被cpu执行的是线程,线程是代码的执行过程,该过程中需要的资源都找对应的进程要 进程是资源的单位,线程是执行单位! 补充:同一个进程里面的多个线程资源是共享的! 2. 为啥要有线程 一个进程里面可以开设多个线程,而开设线程是不需要申请内存空间的(进程需要),因此,开设线程的消耗远…

    2023年4月2日
    00
  • 基础数据类型之字典

    1.字典的定义 使用{}定义字典,括号内用逗号分隔开多个key:value,其中value可以是任意类型,但是key必须是不可变类型且不能重复,是无序的! info=[ [‘name’,’zhang’], (‘age’,19) [‘gender’,’男’] ] d={} # 第一种方式定义 d=dict(x=1,y=2) #第二种,dict里面也可以穿一个i…

    Python开发 2023年4月2日
    00
  • IO模型

    该篇的IO模型主要针对的是网络IO的,其他IO不在本篇考虑范围之内! IO模型简介 Stevens在文章中一共比较了五种IO Model,分别为: * blocking IO 阻塞IO * nonblocking IO 非阻塞IO * IO multiplexing IO多路复用 * signal driven IO 信号驱动IO * asynchronou…

    2023年4月2日
    00
  • 路飞项目前端主页搭建

    前端主页 图片准备 首先把主页需要到图片资源放到项目的img文件夹下 页头组件:components/Header.vue <template> <div class=”header”> <div class=”slogan”> <p>老男孩IT教育 | 帮助有志向的年轻人通过努力学习获得体面的工作和生活&lt…

    2023年4月2日
    00
  • 一切皆对象和深浅拷贝

    1.元类 元类的来源是:python中一切皆对象。 1.1 什么是元类 元类就是用来实例化产生类的类 关系:元类—实例化—类(自定义的类)—实例化—-对象(obj) 1.2如何查看内置的元类 1.type是内置的元类2.我们用class关键字定义出来的所有类以及内置的类都是由内置的元类type实例化产生的 例如:在python中int、dic…

    2023年4月2日
    00
  • for循环语法

    for循环 for循环常用来遍历取值! for循环的基本语法 for 变量名 in 可迭代对象: 代码1 代码2 … # 可迭代对象可以是字典、列表、字符串、元组、集合 for + range range是用来控制for循环次数的方法 for i in range(1,9): print(‘====’) # range(1,9)循环1-8次,括号是顾头不…

    Python开发 2023年4月2日
    00
  • flask基础介绍和语法

    flask基础介绍和语法 flask项目初始化的app.py介绍 # 从flask包中导入flask类 from flask import Flask # 使用flask类实例化出一个app对象 # __name__:代表当前app.py这个模块 app = Flask(__name__) # 创建一个路由和视图的映射 @app.route(‘/’) def…

    2023年4月2日
    00
  • xadmin的使用

    安装 在项目的虚拟环境下执行 pip install https://codeload.github.com/sshwsfc/xadmin/zip/django2 注意:xadmin对于不同django版本有不同的版本,一定要使用相对应的版本 在app中注册 INSTALLED_APPS = [ # … # xadmin主体模块 ‘xadmin’, # …

    Python开发 2023年4月2日
    00
合作推广
合作推广
分享本页
返回顶部