1. 程式人生 > >Django CBV流程及源碼分析

Django CBV流程及源碼分析

向上 數根 數據 註意 djang UNC 冒泡 簡單的 則表達式

Django 實現視圖的方法有兩種,一種是FBV(function base view)即基於函數的視圖,還一種高級的就是CBV(class base view),通過閱讀源碼你會發現它本質上還是基於FBV的。FBV的優點是用法和寫法都比較簡單適合剛開始學的同學使用,缺點就是不能用的面向對象的幾大特性只用函數進行封裝代碼多的時候會顯得代碼很冗余,而CBV就很好的解決了這些問題。並且Django官方在後面的Django版本中加入了很多基於CBV的類,方便我們快速開發。我們先簡單的看下Django在中路由規則的是怎麽定義的,再粗略的看下一FBV,然後再講下我們今天的重點CBV。

  1、Django中路由規則的定義,沒有仔細讀源碼,簡單的講一下

    從這裏進入url的定義:

      技術分享圖片

   這是源碼

      技術分享圖片

   從源碼可以看出,我們在定義路由規則時,第一個參數應該傳入一個正則表達式,第二個參數傳入的就是view,從下面的處理邏輯看,view的類型可以用兩種。第一種是list 或tuple但這種是用來處理include(......)導入的url的,第二種類型就是callable類型的也就是可執行的即函數所以我們在寫FBV的時候一定不要寫上帶上括號,因為url()函數需要的是一個可執行對象。如果傳入這兩種以外的類型就會報錯。我們知道其實include導入 的其實也是一個callable類型的。所以我們可以確定view本質上傳入的是一個可執行的對象,在啟動服務時程序讀取路由將view函數載入內存,接受到請求的時候就會執行這view函數並且返回數據。

理解這一點很重要,這個是FBV和CBV的基礎。  

  2、FBV中視圖的定義和url的寫法

   FBV(基於函數的視圖),定義一個函數根據請求方法的不同而作出相應的處理,註意重點是將對請求的處理封裝在一個函數中。看下例子

   view.py

   技術分享圖片

   定義了一個login函數通過判斷請求的方法進行返回

   url.py

技術分享圖片

   將app01中的views文件導入並將login方法傳給url實現了一個FBV

  3、CBV中視圖的定義和url的寫法

   CBV(基於類的視圖),定義一個類,繼承django.views.View,將處理各種請求方式的邏輯用方法名加處理邏輯封裝在方法裏面,註意重點是將請求的處理封裝在類裏面

   eg:

form dajngo.views import VIew

class Cbv(View):

def a(self, params):
        pass

def b(self, params):

pass

      def get(self, request, *args, **kwargs):

        pass

def post(self, request, *args, **kwargs):

        pass

      def put(self, request, *args, **kwargs):

        pass      

   看下例子:

    view.py 視圖的定義

      技術分享圖片

   url.py 路由的寫法

      技術分享圖片

  4、分析3中的調用過程

在Django項目啟動時路由規則開始載入內存當程序讀到url(r‘^cbv/‘, views.Cbv.as_View())時重點來了,views.Cbv是我們自己定義的一個對象當我們.as_view()的時候就執行了父類的靜態函數as_view方法(根據面向對象的特性可以知道是調用的父類的),我們可以根據在1中得出的結論.as_view()返回的一定是個可調用對象

看下源碼中as_view函數的定義:

  技術分享圖片

可以看到,as_view方法正如我們想的那樣返回的是個可調用對象view,在路由規則載入內存後.as_view的到的其實是個view方法,在接受到請求是才會執行view方法,而view方法的返回值是self.dispatch(request, *args, **kwargs),是由一個實例對象調用的dispatch方法,我們怎麽這個self是誰呢?我們可以一層一層的往上拔從而確定這個實例對象是誰。

self.dispatch(request, *args, **kwargs)是由view()方法調用的,view()方法又是由as_view()方法調用的,as_view()方法又是由views.Cbv調用的,所以我們可以確定self就是Cbv的實例對象,但我們沒有定義dispatch方法所以這個dispatch方法一定在Views類中有定義。

  技術分享圖片

這就是父類中dispatch的定義,先判斷請求是否正確,以get請求為例如果請求正確的話就就利用反射到self中去找與請求方式相對應的方法,根據我們上面的分析self就是我們定義的類Cbv,handler就是我們定義的get方法最後return 我們定義的get方法的返回值。一層一層的向上冒泡,get方法將返回值給dispatch,dispatchs再將返回值給view,到了view這層就和FBV一樣了。

    


     

   

  

Django CBV流程及源碼分析