Django中CBV視圖的源碼分析

前言:Django的視圖處理方式有兩種:

  • FBV(function base views) 是在視圖里基于函數(shù)形式處理請求。
  • CBV(class base views)是在視圖里基于類的形式處理請求。
Python是一個面向對象的編程語言,如果只用函數(shù)來開發(fā),有很多面向對象的優(yōu)點就錯失了(繼承、封裝、多態(tài))。所以Django在后來加入了Class-Based-View??梢宰屛覀冇妙悓慥iew。這樣做的優(yōu)點主要下面兩種:
  • 提高了代碼的復用性,可以使用面向對象的技術,比如Mixin(多繼承)
  • 可以用不同的函數(shù)針對不同的HTTP方法處理,而不是通過很多if判斷,提高代碼可讀性

那下面我們來看一下django的源碼,從而進一步了解Django的CBV

一、首先看url:

url:

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

django的CBV在url中的書寫需要在view.類名后加.as_view(),從中可以了解到as_view一定是一個方法,這個方法加上了(),是在Django項目啟動時就自動執(zhí)行的,返回值也應該是 一個函數(shù)名,從而在匹配url后可以執(zhí)行相應的函數(shù)

PS:關于分析源碼的首要任務是需要清楚方法的調用者self的歸屬類?。。『苤匾?br> 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

源碼執(zhí)行簡易流程圖:


1.png

到此可以很明顯的看出,Django項目啟動后,CBV下的url執(zhí)行后相當于:

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

二、接下來當有用戶訪問url時,對應url的view會執(zhí)行對應請求方式下的類方法

源碼:以下源碼注意兩點 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'))

源碼: 執(zhí)行對應的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的源碼執(zhí)行流程就結束了,很好的利用了python面向對象的三大特性:繼承、封裝和多態(tài)??赐暝创a,是不是感覺python的面向對象有時候用起來意猶未盡。。。。。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 1、通過CocoaPods安裝項目名稱項目信息 AFNetworking網(wǎng)絡請求組件 FMDB本地數(shù)據(jù)庫組件 SD...
    陽明AI閱讀 16,205評論 3 119
  • ?這一天,我們玩了泡泡袋畫。 材料: 一個裝快遞的氣泡袋,氣泡一個一個凸起的圓形,印在紙上很有趣又好看。 顏料 一...
    媽咪私塾閱讀 1,296評論 2 20
  • 悲傷與盡頭 不知淚何物 眼前皆虛無 只求真實襲 無需酒解愁 無需被人憐 無需看世界 只求一角落 無淚乃悲涼 有淚卻...
    然心江閱讀 291評論 2 4
  • 前兩天還吐槽庸俗化的極挑,差點沒把我淚奔,時間這場回不去的旅途啊,希望我們都別把它看輕,你現(xiàn)在所擁有的,都是以后懷念的。
    丸子倩閱讀 186評論 0 0

友情鏈接更多精彩內容