django中CBV视图模式的View源码分析

位置:

1.找到自己项目用的解释器存储位置
H:\pythonProject\Lib\site-packages\django\views\generic\base.py
在base.py里有一个View类

2.也可以通过from django.views import View 按住ctrl点击View会直接跳到该类的位置

CBV形式的路由

path(r'^login/',views.MyLogin.as_view())

CBV形式的视图函数

from django.views import View
class MyLogin(View):
def get(self,request): #get请求时执行的函数
	return render(request,'form.html')
def post(self,request):  #post请求时执行的函数
	return HttpResponse('post方法')

CBV源码分析:

当上述的login请求来了之后---》会执行后面的views.MyLogin.as_view()---》这个地方应该放的是函数的内存地址,views.MyLogin.as_view()执行完,是个函数内存地址,---views.MyLogin.as_view()会去views.py中找到MyLogin这个类,然后找as_view()方法,发现没有--》去其父类中找就是View类中找---》执行as_view()方法最终返回的是一个View类内部的一个view函数内存地址---》然后django框架会自动给view这个函数加括号调用,再传入request这个参数--->而view这个内部函数返回的是return handler(request, *args, **kwargs)就是对应类中get或者post方法

as_view()方法分析:

@classonlymethod # 1.这个as_view是一个类方法,所以用类调用时,会自动把调用的类传入给这个函数的cls
def as_view(cls, **initkwargs):
    """Main entry point for a request-response process."""
    # 2.因为url那边没有传参,所以initkwargs为空,先忽略该层代码
    for key in initkwargs:
        if key in cls.http_method_names:
            raise TypeError(
                "The method name %s is not accepted as a keyword argument "
                "to %s()." % (key, cls.__name__)
            )
        if not hasattr(cls, key):
            raise TypeError(
                "%s() received an invalid keyword %r. as_view "
                "only accepts arguments that are already "
                "attributes of the class." % (cls.__name__, key)
            )

    # 3.执行该view函数
    def view(request, *args, **kwargs): # request是当次请求的数据
        # 5.cls是当前调用的类MyLogin,cls加括号产生对象给了self,这里现在self就是类MyLogin产生的对象
        self = cls(**initkwargs)
        self.setup(request, *args, **kwargs)
        if not hasattr(self, "request"):
            raise AttributeError(
                "%s instance has no 'request' attribute. Did you override "
                "setup() and forget to call super()?" % cls.__name__
            )
        # 6.view函数返回了self.dispatch(request, *args, **kwargs)方法,
        # self本身没有dispatch方法,就去MyLogin中找,MyLogin没有就去View类中找,找到了
        return self.dispatch(request, *args, **kwargs)

    view.view_class = cls
    view.view_initkwargs = initkwargs

    # __name__ and __qualname__ are intentionally left unchanged as
    # view_class should be used to robustly determine the name of the view
    # instead.
    view.__doc__ = cls.__doc__
    view.__module__ = cls.__module__
    view.__annotations__ = cls.dispatch.__annotations__
    # Copy possible attributes set by decorators, e.g. @csrf_exempt, from
    # the dispatch method.
    view.__dict__.update(cls.dispatch.__dict__)

    # Mark the callback if the view class is async.
    if cls.view_is_async:
        view._is_coroutine = asyncio.coroutines._is_coroutine

    # 4.as_view返回的是该函数内部的view函数内存地址,所以具体读下view函数就行
    return view

上述as_view()方法返回了一个dispatch方法,dispatch方法分析:

# 1.dispatch将MyLogin这个类产生的对象self和request请求对象传入了dispatch
def dispatch(self, request, *args, **kwargs):
    # Try to dispatch to the right method; if a method doesn't exist,
    # defer to the error handler. Also defer to the error handler if the
    # request method isn't on the approved list.
    # 2.判断request.method方法在不在http_method_names里,ttp_method_names对象里没有最后去View类里找到了
    if request.method.lower() in self.http_method_names:
        # 3.通过getattr方法反射,self.http_method_not_allowed这个就当没有前面的方法时的一个默认值
        # handler最后得到的就是MyLogin中定义的get或者post方法的内存地址
        handler = getattr(
            self, request.method.lower(), self.http_method_not_allowed
        )
    else:
        handler = self.http_method_not_allowed
    # 4.最后这个方法将handler加括号,再传入request参数调用的结果返回出去==执行了MyLogin的get或者post方法
    return handler(request, *args, **kwargs)

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:django中CBV视图模式的View源码分析 - Python技术站

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

相关文章

  • 登录注册接口搭建

    登录接口分析 登录分为多方式登录和验证码登录方式 多方式登录 1)前台提供账号密码,账号可能是 用户名、手机号、邮箱等 接口: 后台只需要提供一个多方式登录接口即可 – 多方式登录接口 多方式登录接口 前端输入完账号和密码,点击登录,向后端发送请求进行校验用户登录数据 urls.py from django.urls import path,re_path,…

    Python开发 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
  • flask操作数据库

    flask操作数据库 准备工作 安装flask-script(版本过高可能会报错) pip install flask-script==2.0.3 使用flask-script里的Manager类实例化来管理项目的启动等 from apps import create_app from flask_script import Manager app = cr…

    2023年4月2日
    00
  • 支付宝支付

    支付宝支付流程 在python中封装alipay 安装 >: pip install python-alipay-sdk –upgrade # 如果抛ssl相关错误,代表缺失该包 >: pip install pyopenssl 结构 libs ├── AliPay # aliapy二次封装包 │ ├── __init__.py # 包文件 │…

    2023年4月2日
    00
  • git的介绍和使用

    git介绍 什么是git git是一种版本控制器 – 控制的对象是开发的项目代码 什么是版本控制器 完成 协同开发 项目,帮助程序员整合代码 i)帮助开发者合并开发的代码 ii)如果出现冲突代码的合并,会提示后提交合并代码的开发者,让其解决冲突 软件:SVN 、 GIT(都是同一个人的个人项目) github、gitee(两个采用git版本控制器管理代码的公…

    2023年4月2日
    00
  • 实时展示用户上传的头像

    实时展示用户上传的头像 总体思路 “”” 1.首先需要给对应的上传头像input框绑定一个文本域变化事件 (当检测到用户对该文件框上传了头像就会触发一系列操作) 2.再生成一个文件阅读器对象 3.再获取用户上传的文件头像 4.把用户上传的文件头像交给文件阅读器对象FileReader读取 5.利用文件阅读器把读取的文件头像结果展示到前端页面 (修改img的s…

    Python开发 2023年4月2日
    00
  • 序列化类高级用法之source、SerializerMethodField和断言assert

    序列化类高级用法之source 使用source,字段参数,可以修改序列化字段名字 原本序列化器中字段名,必须和表中的字段名一样,不一样会报错 我们可以通过source字段来改变序列化器中的字段名,使得前端在展示的时候也修改一下字段名!! source也可以做跨表查询,通过外键字段,表名点外键出去的字段名字 class BookSerializer(seri…

    2023年4月2日
    00
  • django中视图函数的FBV和CBV

    1.什么是FBV和CBV FBV是指视图函数以普通函数的形式;CBV是指视图函数以类的方式。 2.普通FBV形式 def index(request): return HttpResponse(‘index’) 3.CBV形式 3.1 CBV形式的路由 path(r’^login/’,views.MyLogin.as_view()) 3.2 CBV形式的视图…

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