Django CBV原始碼分析
django檢視層中FBV與CBV
簡介
檢視函式既可以是函式也可以是類
FBV(function base views)
就是在視圖裡使用函式處理請求,在之前django的學習中,一直使用的方式
CBV(class base views)
CBV基本使用
就是在視圖裡使用類處理請求
Python是一個面向物件的程式語言,如果只用函式來開發,有很多面向物件的優點就錯失了(繼承、封裝、多型)。所以Django在後來加入了Class-Based-View。可以讓我們用類寫View。這樣做的優點主要下面兩種:
- 提高了程式碼的複用性,可以使用面嚮物件的技術,比如Mixin(多繼承)
- 可以用不同的函式針對不同的HTTP方法處理,而不是通過很多if判斷,提高程式碼可讀性
CBV原始碼分析
當瀏覽器客戶端向服務端傳送請求時,會先通過路由匹配到對應的檢視函式並加括號呼叫。
在路由層中書寫的路由與檢視函式的對應關係,路由對應的必須是一個函式地址,因此CBV本質還是FBV,由此可以推斷views.MyView.as_view()
中的as_view應該是一個類方法,並且該方法加括號呼叫後返回的結果是一個函式的記憶體地址。
as_view方式是自定義檢視類呼叫的,但是自定義檢視類MyView
中並沒有該方法,按照面向物件的屬性查詢順序,as_view方法是在MyView
的父類View
中定義的
- 進入as_view方法
當匹配到檢視類的時候,會加()
執行views.MyView.as_view()
views.MyView.as_view()
執行的結果是返回as_view方法內部的view
函式的記憶體地址
在self.setup
方法中,會將當次請求的request物件作為屬性新增給當前物件
路由對應的是view方法的記憶體地址,因此當匹配到路由時會加()
執行view
方法
根據上圖可以發現,執行view
方法會返回self.dispatch()
方法的執行結果
在dispatch方法中會獲取物件(MyView
的物件)的請求方式然後小寫,判斷是否在self.http_method_names
中,如果在就通過反射將物件的請求方式小寫賦值給handler,,最後返回handler加()
呼叫。
CBV檢視層中,dispatch方法可以說是前端向後端傳送請求的排程員,可以根據不同的請求的方式執行檢視類中對應的方法
例如:前端向後端根據url傳送了get請求,後端會根據路由與檢視的對應關係執行對應的檢視類,就會執行as_view方法,通過執行as_view方式,返回了view方法的記憶體地址,加()呼叫,
view()
的執行會返回dispatch方法的執行,在dispatch方法中獲取到前端傳送請求的方式,然後小寫,即為get,最後返回get加()
呼叫