• CBV


    一、CBV与FBV

    #Class Base View(基于类的视图)
    #Function Base View(基于函数的视图)


    二、CBV的用法及源码分析

    1、用法

    #视图层
    # 1 先导入View(继承它)
    from django.views import View
    # 写一个类继承它,
    class Test(View):
         #request必须传,后面的可传可不传(有可能有名,无名分组)
        def get(self, request, *args, **kwargs):
            print('get')
            return render(request, 'login.html')
        def post(self, request):
            name = request.POST.get('name')
            pwd = request.POST.get('pwd')
            if name == 'pdun' and pwd == '123':
                return HttpResponse('登录成功')
            else:
                return render(request, 'login.html', {'error': '用户名或密码错误'})
    
    #路由层
    urlpatterns = [
        # as_view一定要加括号,as_view()哪里来的?  从View中继承过来的
        # as_view用类来调用的,它是一个类方法
        # 猜:as_view这个方法执行完成以后,应该是个函数的内存地址
        # 如果是get请求,会响应到类内部,执行get方法post请求,一样
        # as_view 类方法,自动把自己传过来
        url(r'^login/', views.Test.as_view()),
    
    
    #模板层与FBV相同
    <body>
    <form action="" method="post">
        <p>用户名: <input type="text" name="name"></p>
        <p>密码: <input type="password" name="pwd"></p>
        <p><input type="submit" value="提交">{{ error }}</p>
    </form>
    </body>
    View Code

    2、源码分析

    #View类中有1个数据属性,6个方法属性
    
    class View(object):
        http_method_names = ['get', 'post', ' 'trace'。。。]
    
        def __init__(self, **kwargs):
    
        @classonlymethod
        def as_view(cls, **initkwargs): 
                def view(request, *args, **kwargs):
        
        def dispatch(self, request, *args, **kwargs):
    
        def http_method_not_allowed(self, request, *args, **kwargs):
    
        def options(self, request, *args, **kwargs):
    
        def _allowed_methods(self):
    路由层as_view
    #调用顺序: 请求来了---->as_view --> view --> dispatch----->分发到不同的函数(自己写的类中的get,post)
        可以看出as_view实际上是一个闭包,他的作用就是做一些检验工作,再返回view方法
        而view方法的作用是给请求对象补充三个参数,并调用dispatch方法处理
        dispatch方法查找到指定的请求方法,并执行相应代码块
    #可以得出结论:as_view方法实际上最后就是要调用dispatch方法
    #路由
        url(r'^login/', views.Login.as_view()),
    class View(object):
         http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
    
        @classonlymethod
        def as_view(cls, **initkwargs):
    
            def view(request, *args, **kwargs):    #这是一个闭包函数
                self = cls(**initkwargs)
    
                  #判断self类中是不是有该(get)方法 
                if hasattr(self, 'get') and not hasattr(self, 'head'):
                    self.head = self.get
                self.request = request     #这几个是赋值
                self.args = args
                self.kwargs = kwargs
    
                 #最后执行的是dispatch方法,自己的类中一般不重写这个方法,所以执行view的中的该方法
                return self.dispatch(request, *args, **kwargs)
            view.view_class = cls
            view.view_initkwargs = initkwargs
            return view
    
        def dispatch(self, request, *args, **kwargs):
    
                    #request.method 前台请求的方法,转成了小写并判断在不在列表中
            if request.method.lower() in self.http_method_names:
    
                             #getattr的第三个参数是默认值:self.http_method_not_allowed
                #拿到get方法的内存地址
                handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
    
            else:
                handler = self.http_method_not_allowed
            return handler(request, *args, **kwargs)    
    View Code
    #闭包函数,内部函数包含外部函数的名称空间
    def bar():
        x=8
        y=8
        def inner():
            q=x+y
            print(q)
        inner.x=1          #注意这里,不是更改X
        print(inner.__dict__)
        return inner
    bar()()
    
    
    {'x': 1}
    16
    辅助源码理解
    #读源码总结
    
    #CBV:基于类的视图
    #导入from django.views import View
    #自定义类继承View
    
    #自定义的类中只能是如下方法:
        #http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
    
        #请求流程:as_view() 的返回值是他内部view函数的内存地址
        #dispatch方法,总的分发方法
        #补充:装饰器的装饰方法
            url(r'^test/', csrf_exempt(views.test)),
            
    #总结:
    #路由配置好,项目启动:as_view()---->返回结果是一个函数的内存地址
    #请求来了---->触发函数的执行,就会执行dispatch方法---->根据请求的不同,分发到不同的视图函数
  • 相关阅读:
    pickle 序列化对象
    字符串模板
    静态类和静态方法,抽象类和抽象方法,new关键字,值类型和引用类型,接口
    C#中方法,方法声明,方法调用和方法重载!
    TryParse用法
    成倍提高服务器的负载能力:浅谈Jexus的ASP.NET前置缓存技术
    全面解析C#中参数传递
    【NX二次开发】Block UI 属性类型
    【NX二次开发】镜像对象
    【NX二次开发】根据视图名称旋转视图,在布局中替换视图uc6464
  • 原文地址:https://www.cnblogs.com/pdun/p/10872430.html
Copyright © 2020-2023  润新知