django的as_view方法實(shí)現(xiàn)分析

django的類視圖擁有自動(dòng)查找指定方法的功能, 通過調(diào)用是通過as_view()方法實(shí)現(xiàn)

urls.py

from meduo_mall.demo import views

urlpatterns = [
    url(r'register/$', views.Demo.as_view())
]

views.py

from django.views.generic import View


class Demo(View):

    def get(self, request):
        return HttpResponse('get page')

    def post(self, request):
        return HttpResponse('post page')

為什么as_view能自動(dòng)匹配指定的方法,

先看源碼

    @classonlymethod
    def as_view(cls, **initkwargs):  # 實(shí)際上是一個(gè)閉包  返回 view函數(shù)
        """
        Main entry point for a request-response process.
        """
        for key in initkwargs:
            if key in cls.http_method_names:
                raise TypeError("You tried to pass in the %s method name as a "
                                "keyword argument to %s(). Don't do that."
                                % (key, cls.__name__))
            if not hasattr(cls, key):
                raise TypeError("%s() received an invalid keyword %r. as_view "
                                "only accepts arguments that are already "
                                "attributes of the class." % (cls.__name__, key))

        def view(request, *args, **kwargs):  # 作用:增加屬性, 調(diào)用dispatch方法 
            self = cls(**initkwargs)  # 創(chuàng)建一個(gè) cls 的實(shí)例對(duì)象, cls 是調(diào)用這個(gè)方法的 類(Demo)
            if hasattr(self, 'get') and not hasattr(self, 'head'):
                self.head = self.get
            self.request = request  # 為對(duì)象增加 request, args, kwargs 三個(gè)屬性
            self.args = args
            self.kwargs = kwargs
            return self.dispatch(request, *args, **kwargs)  # 找到指定的請(qǐng)求方法, 并調(diào)用它
        view.view_class = cls
        view.view_initkwargs = initkwargs

        # take name and docstring from class
        update_wrapper(view, cls, updated=())

        # and possible attributes set by decorators
        # like csrf_exempt from dispatch
        update_wrapper(view, cls.dispatch, assigned=())
        return view

    def dispatch(self, request, *args, **kwargs):
        # Try to dispatch to the right method; if a method doesn't exist,
        if request.method.lower() in self.http_method_names:  # 判斷請(qǐng)求的方法類視圖是否擁有, http_method_names=['get', 'post']
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)  # 如果存在 取出該方法
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)  # 執(zhí)行該方法

簡(jiǎn)化版

    @classonlymethod
    def as_view(cls, **initkwargs):  # 實(shí)際上是一個(gè)閉包  返回 view函數(shù)
        """
        Main entry point for a request-response process.
        """
        def view(request, *args, **kwargs):  # 作用:增加屬性, 調(diào)用dispatch方法 
            self = cls(**initkwargs)  # 創(chuàng)建一個(gè) cls 的實(shí)例對(duì)象, cls 是調(diào)用這個(gè)方法的 類(Demo)
            if hasattr(self, 'get') and not hasattr(self, 'head'):
                self.head = self.get
            self.request = request  # 為對(duì)象增加 request, args, kwargs 三個(gè)屬性
            self.args = args
            self.kwargs = kwargs
            return self.dispatch(request, *args, **kwargs)  # 找到指定的請(qǐng)求方法, 并調(diào)用它

        return view

    def dispatch(self, request, *args, **kwargs):
        # Try to dispatch to the right method; if a method doesn't exist,
        if request.method.lower() in self.http_method_names:  # 判斷請(qǐng)求的方法類視圖是否擁有, http_method_names=['get', 'post']
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)  # 如果存在 取出該方法
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)  # 返回該請(qǐng)求方法執(zhí)行的結(jié)果

再簡(jiǎn)化

def as_view(): # 校驗(yàn) + 返回view方法
    # 一些校驗(yàn)
    ...
    def view(): # 執(zhí)行視圖
        # 增加 為對(duì)象request, args, kwargs 屬性
        ...
        return dispatch() # 調(diào)用指定的請(qǐng)求方法
    return view

def dispatch(): # 真正的查找指定的方法, 并調(diào)用該方法
    ...
    return handler()
調(diào)用順序: as_view --> view --> dispatch
  • 可以看出as_view實(shí)際上是一個(gè)閉包, 它的作用做一些校驗(yàn)工作, 再返回view方法.

  • view方法的作用是給請(qǐng)求對(duì)象補(bǔ)充三個(gè)參數(shù), 并調(diào)用 dispatch方法處理

  • dispatch方法查找到指定的請(qǐng)求方法, 并執(zhí)行

可以得出結(jié)論: 實(shí)際上真正實(shí)現(xiàn)查找的方法是 dispatch方法

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

相關(guān)閱讀更多精彩內(nèi)容

  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時(shí)...
    歐辰_OSR閱讀 30,260評(píng)論 8 265
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,668評(píng)論 1 32
  • 1、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫組件 SD...
    陽明AI閱讀 16,211評(píng)論 3 119
  • 已經(jīng)同步到gitbook,想閱讀的請(qǐng)轉(zhuǎn)到gitbook: Django 1.10 中文文檔 URL dispatc...
    leyu閱讀 14,441評(píng)論 0 16
  • 170403@D89.感恩冥想 佩詩 。深深的感恩慈悲偉大的佛陀,感謝感謝感謝! 。感恩格西老師用現(xiàn)代化的語言教授...
    佩詩閱讀 146評(píng)論 0 0

友情鏈接更多精彩內(nèi)容