Django的method_decorator等裝飾器的改進

本文希望給大家提供一些思路,拋磚引玉。不要侷限於Django提供的手段,完全可以爲項目自己重新適合的裝飾器。



Django提供的內建的視圖用的裝飾器,個人認爲並不好用,它能很好的適合視圖函數,但是不能直接用在視圖類的方法上,歸根結底就是self的問題。

當URL映射到視圖函數時,第一個實參就是request,但是如果使用視圖類,那麼as_view()雖然分把類封裝的像函數一樣,但是調用函數時,使用的是類的實例即視圖實例。

也就是說as_view()內部本質上就是封裝類返回一個包裝函數view,每次URL請求來了就調用這個view函數,臨時創建視圖類實例,並使用self調用了dispatch調度到get或post等方法,在dispatch內部使用了getattr反射。


網上各種在視圖類cbv的dispatch函數加裝飾器的方法,個人認爲並不好。本文知識簡單處理,如果有空,下一篇文章將重新封裝自己寫的wrapper_method_before和wrapper_method_after裝飾器


from django.views.decorators.csrf import csrf_protect
# csrf_protect就是強行在視圖函數前執行CsrfViewMiddleware,相當於臨時打開了CsrfViewMiddleware中間件
# from django.utils.decorators import method_decorator # 使用自己寫的裝飾器替換它

def wrapper_method_before(func):
    """在django的視圖裝飾器上面用"""
    from django.views import View
    def wrapper(*args, **kwargs):
        firstparam = args[0]
        if isinstance(firstparam, View):
            kwargs.update(viewinstance=firstparam)
            ret = func(*args[1:], **kwargs)
        else:
            ret = func(*args, **kwargs)
        return ret
    return wrapper

def wrapper_method_after(func):
    """在django的視圖裝飾器下面用"""
    def wrapper(*args, **kwargs):
        view = kwargs.pop('viewinstance', None)
        if view is None:
            ret = func(*args, **kwargs)
        else:
            ret = func(view, *args, **kwargs)
        return ret
    return wrapper



class PostView(View):
    @wrapper_method_before # 把視圖實例挪走
    @csrf_protect # 必須csrf驗證通過
    @wrapper_method_after # 把視圖實例挪回來
    @login_required # 自己寫的裝飾器替換Django的,內部也修正了self的問題
    def post(self, request: HttpRequest):
        pass


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章