Django之CBV視圖源碼分析(工做原理)

1.首先咱們先在urls.py定義CBV的路由匹配。
python

FBV的路由匹配:app

2.而後,在views.py建立一名爲MyReg的類:函數

注意:該類必須繼續View類,且方法名必須與請求方式相同(後面會詳解)url

3.回到第一步的路由匹配能夠看到MyReg.as_view(),直接調用了as_view函數。那麼如今進去as_view函數看看裏面運行了什麼?spa

4.由上面的分析能夠知道執行as_view函數時,返回該函數下嵌套的一個叫view函數的內存地址,這樣,urls.py裏的url(r'^my_reg/', views.MyReg.as_view())就至關於url(r'^my_reg/', views.view)了,這樣跟咱們以前的FBV就沒區別了,當url匹配成功,就會執行view函數。code

5.假設url匹配成功,執行view函數:blog

首先view函數完成了MyReg類的初始化內存

最後view函數 先調用dispatch函數, 而後返回dispatch函數執行後返回值,路由

6.如今進入dispatch函數看看它返回了什麼數據字符串

dispatch函數爲CBV最精髓的部分

分析:

request.method.lower()爲請求方式的小寫

self.http_method_names點進去爲一個列表,該列表是全部八個請求方式的小寫

self.http_method_not_allowed返回一個報錯信息爲405的函數

getattr是反射,經過字符串獲取方法的內存地址。拿到內存地址能夠直接加()調用

最後總分析 dispatch函數

def dispatch(self, request, *args, **kwargs):
        # Try to dispatch to the right method; if a method doesn't exist,
        # defer to the error handler. Also defer to the error handler if the
        # request method isn't on the approved list.
        # 判斷用戶發送的請求方式是否在http_method_names列表裏面
        if request.method.lower() in self.http_method_names:  
            # 經過反射判斷MyReg類是否有跟請求方式同名的方法,如有,返回該方法的內存地址,沒有返回報錯405
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            # 若是不在就返回一個報錯405的函數
            handler = self.http_method_not_allowed
        # 最後直接執行上面返回的函數
        return handler(request, *args, **kwargs)
相關文章
相關標籤/搜索