django的cbv

FBV

FBV(function base views) 就是在視圖里使用函數(shù)處理請求鳍怨。

在之前django的學(xué)習(xí)中,我們一直使用的是這種方式傲隶,所以不再贅述鹅经。

CBV

CBV(class base views) 就是在視圖里使用類處理請求寂呛。

Python是一個面向?qū)ο蟮木幊陶Z言,如果只用函數(shù)來開發(fā)瘾晃,有很多面向?qū)ο蟮膬?yōu)點就錯失了(繼承贷痪、封裝、多態(tài))蹦误。所以Django在后來加入了Class-Based-View劫拢。可以讓我們用類寫View强胰。這樣做的優(yōu)點主要下面兩種:

  1. 提高了代碼的復(fù)用性舱沧,可以使用面向?qū)ο蟮募夹g(shù),比如Mixin(多繼承)
  2. 可以用不同的函數(shù)針對不同的HTTP方法處理偶洋,而不是通過很多if判斷熟吏,提高代碼可讀性

CBV.as_view()

在Django的路由中為url指定view的時候,如果為類視圖(所有類視圖都需要繼承于基類View)玄窝,則需要使用as_view方法將類視圖轉(zhuǎn)化為一個函數(shù)牵寺,接下來筆者就分析一下as_view方法的源碼。

class View(object):
    """
    Intentionally simple parent class for all views. Only implements
    dispatch-by-method and simple sanity checking.
    """

    http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

    def __init__(self, **kwargs):
        """
        Constructor. Called in the URLconf; can contain helpful extra
        keyword arguments, and other things.
        """
        # Go through keyword arguments, and either save their values to our
        # instance, or raise an error.
        for key, value in six.iteritems(kwargs):
            setattr(self, key, value)

    # as_view方法經(jīng)過類方法裝飾器恩脂,是一個類方法
    @classonlymethod
    def as_view(cls, **initkwargs):
        """
        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):
            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)
        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,
        # defer to the error handler. Also defer to the error handler if the
        # request method isn't on the approved list.
        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)

    def http_method_not_allowed(self, request, *args, **kwargs):
        logger.warning(
            'Method Not Allowed (%s): %s', request.method, request.path,
            extra={'status_code': 405, 'request': request}
        )
        return http.HttpResponseNotAllowed(self._allowed_methods())

其實as_view方法在方法中定義了一個view函數(shù)帽氓,這個函數(shù)接受的參數(shù)跟FBV接受的參數(shù)一樣,但是這個函數(shù)并不負(fù)責(zé)根據(jù)http的method分配到具體的CBV的method上俩块,而是將這項工作交給了dispatch方法去完成黎休。最后as_view方法返回了這個view函數(shù)浓领。

在dispatch方法中,尋找了開發(fā)者自行定義的諸如get势腮,post等方法對應(yīng)的業(yè)務(wù)邏輯并返回執(zhí)行結(jié)果联贩,如果開發(fā)者沒有定義該方法,則返回405表示該方法不允許捎拯。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末撑蒜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子玄渗,更是在濱河造成了極大的恐慌,老刑警劉巖狸眼,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件藤树,死亡現(xiàn)場離奇詭異,居然都是意外死亡拓萌,警方通過查閱死者的電腦和手機(jī)岁钓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來微王,“玉大人屡限,你說我怎么就攤上這事】惶龋” “怎么了钧大?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長罩旋。 經(jīng)常有香客問我啊央,道長,這世上最難降的妖魔是什么涨醋? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任瓜饥,我火速辦了婚禮,結(jié)果婚禮上浴骂,老公的妹妹穿的比我還像新娘乓土。我一直安慰自己,他們只是感情好溯警,可當(dāng)我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布趣苏。 她就那樣靜靜地躺著,像睡著了一般愧膀。 火紅的嫁衣襯著肌膚如雪拦键。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天檩淋,我揣著相機(jī)與錄音芬为,去河邊找鬼萄金。 笑死,一個胖子當(dāng)著我的面吹牛媚朦,可吹牛的內(nèi)容都是我干的氧敢。 我是一名探鬼主播,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼询张,長吁一口氣:“原來是場噩夢啊……” “哼孙乖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起份氧,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤唯袄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蜗帜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體恋拷,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年厅缺,在試婚紗的時候發(fā)現(xiàn)自己被綠了蔬顾。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡湘捎,死狀恐怖诀豁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情窥妇,我是刑警寧澤舷胜,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站秩伞,受9級特大地震影響逞带,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜纱新,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一展氓、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧脸爱,春花似錦遇汞、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至族檬,卻和暖如春歪赢,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背单料。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工埋凯, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留点楼,地道東北人。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓白对,卻偏偏與公主長得像掠廓,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子甩恼,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,500評論 2 359

推薦閱讀更多精彩內(nèi)容