zoukankan      html  css  js  c++  java
  • django中CBV源码分析

    前言:Django的视图处理方式有两种:

    • FBV(function base views) 是在视图里基于函数形式处理请求。
    • CBV(class base views)是在视图里基于类的形式处理请求。
    Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承、封装、多态)。所以Django在后来加入了Class-Based-View。可以让我们用类写View。这样做的优点主要下面两种:
    • 提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
    • 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性

    那下面我们来看一下django的源码,从而进一步了解Django的CBV

    一、首先看url:

    url:

    url(r'register/$',views.Register.as_view())
    

    django的CBV在url中的书写需要在view.类名后加.as_view(),从中可以了解到as_view一定是一个方法,这个方法加上了(),是在Django项目启动时就自动执行的,返回值也应该是 一个函数名,从而在匹配url后可以执行相应的函数

    PS:关于分析源码的首要任务是需要清楚方法的调用者和self的归属类!!!很重要
    view.py:

    class Register(View):
    
        def get(self,request):
            return render(request, 'register.html')
    

    源码:

        @classonlymethod
        def as_view(cls, **initkwargs):
            pass
            def view(request, *args, **kwargs):
                self = cls(**initkwargs)
                if hasattr(self, 'get') and not hasattr(self, 'head'):
                    self.head = self.get
                self.request = request
                self.args = args
                self.kwargs = kwargs
                return self.dispatch(request, *args, **kwargs)
    
            return view
    

    源码执行简易流程图:

     
    1.png

    到此可以很明显的看出,Django项目启动后,CBV下的url执行后相当于:

    url(r'register/$',views.Register.view)
    

    二、接下来当有用户访问url时,对应url的view会执行对应请求方式下的类方法

    源码:以下源码注意两点 1. cls涉及到了----《闭包作用域 》; 2. self的指向

        @classonlymethod
        def as_view(cls, **initkwargs):
            pass
    
            def view(request, *args, **kwargs):
                self = cls(**initkwargs)    //cls是Register类,self是实例化的对象
                if hasattr(self, 'get') and not hasattr(self, 'head'):
                    self.head = self.get
                self.request = request
                self.args = args
                self.kwargs = kwargs
                return self.dispatch(request, *args, **kwargs)
    
            return view
    

    view.py: 找dispatch方法时需要先找自己类中,没有再找继承类中

    class Register(View):
    
        def get(self,request):
            return render(request, 'register.html'))
    

    源码: 执行对应的dispatch方法

       def dispatch(self, request, *args, **kwargs):
    
            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
            return handler(request, *args, **kwargs)
    
     
    7.png

    到此Django基于CBV的源码执行流程就结束了,很好的利用了python面向对象的三大特性:继承、封装和多态。

    此文章来自于https://www.jianshu.com/p/9e4e3195d731

  • 相关阅读:
    一个封装好的CSV文件操作C#类代码
    C#导出GridView数据到Excel文件类
    JQ获取选中select 标签的值
    JQ替换标签与内容
    layerUi与AJAX的一种思路
    .NET MVC同页面显示从不同数据库(mssql、mysql)的数据
    MVC Html辅助方法DropDownList的简单使用、连接MYSQL数据库用自定义model类接收
    EF中GroupBy扩展方法的简单使用
    sqlserver操作命令
    发送短信验证码及调用短信接口与C# 后台 post 发送
  • 原文地址:https://www.cnblogs.com/YZL2333/p/11684735.html
Copyright © 2011-2022 走看看