Django中CBV视图的源码分析

作者: SlashBoyMr_wang | 来源:发表于2018-09-17 16:15 被阅读58次

前言: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面向对象的三大特性:继承、封装和多态。看完源码,是不是感觉python的面向对象有时候用起来意犹未尽。。。。。

相关文章

  • Django基础:drf 源码视图解析

    Django 与drf 源码视图解析 一.原生Django CBV 源码分析:View 二.drf CBV 源码分...

  • Django-CBV源码分析

    django——CBV源码分析 FBV(function base views) 就是在视图里使用函数处理请求.C...

  • Django中CBV视图的源码分析

    前言:Django的视图处理方式有两种: FBV(function base views) 是在视图里基于函数形式...

  • DRF进阶

    一、Django的FBV和CBV FBV:Function-base views基于函数的视图CBV:Class-...

  • Rest framework-APIView简单源码分析

    REST-APIView源码分析 前言:APIView基于View 看这部分内容一定要懂django—CBV里的内...

  • Django 的 cbv

    正如我们了解到的,Django 写视图函数有两种写法:cbv 和 fbv。cbv 提倡使用类来写,fbv 使用函数...

  • 2018-04-24

    关于Django REST framework源码认证流程的简单分析 一个URL对应一个视图函数,视图函数又可...

  • Django报错:AttributeError: 'functi

    在学习Django视图策略的时候,使用基于类的视图 (CBV),遇到了一个问题: re_path(r'^new_p...

  • Django中的CBV

    django中请求处理方式有2种:FBV 和 CBV CBV CBV(class base views) 就是在视...

  • Django中CBV

    一.django处理业务逻辑的两种方式 FBV (function based views):使用函数来处理业务逻...

网友评论

    本文标题:Django中CBV视图的源码分析

    本文链接:https://www.haomeiwen.com/subject/cvplnftx.html