django class類即視圖類添加裝飾器的幾種方法


根據別人發布整理,個人愛好收集(原文:https://blog.csdn.net/mydistance/article/details/83958655 )

第一種:定義函數裝飾器,在函數,類中使用函數裝飾器

一、定義視圖類

定義類視圖,且類視圖繼承自View(舉例)

from django.views.generic import View
 
class DemoView(View):
 
        """
    具體的視圖函數
        """

定義路由:

urlpatterns = [
    # 類視圖:注冊
    url(r'^register/$',views.DemoView.as_view()),
]

類視圖的好處:
代碼可讀性好,類視圖相對於函數視圖有更高的復用性

二、視圖類使用裝飾器:

定義一個裝飾器:

def my_decorator(func):
    
    def wrapper(request, *args, **kwargs): 
        print('自定義裝飾器被調用了')
        print('請求路徑%s' % request.path)        
        return func(request, *args, **kwargs) 
    return wrapper

方法一:在url配置中裝飾:

urlpatterns = [
    # 我們在路由部分, 把定義好的裝飾器添加到當前的函數上
    # 這里需要注意: as_view() 會返回一個 view() 函數
    # 所以我們把裝飾器添加到view()函數上.
    url(r'^demo/$', views.my_decorate(views.DemoView.as_view()))
]

弊端:單看視圖的時候,無法知道此視圖還被添加了裝飾器,不利於代碼的完整性;此種方法會為類視圖中的所有請求方法都加上裝飾器行為

方法二:調用系統的裝飾器(給某個視圖函數添加裝飾器)
需要使用method_decorator將其轉換為適用於類視圖方法的裝飾器,這種方法直接將裝飾器應用在了具體的視圖函數上,哪個視圖函數需要,就給他添加。

@method_decorator(my_decorator)
def get(self, request):
    print('get方法')
    return HttpResponse('ok')

方法三:在類上面添加(給所有的視圖函數都添加裝飾器)

@method_decorator(my_decorator, name='dispatch')
class DemoView(View):

還可以列表方式並帶跳轉進行添加
@method_decorator([login_required(login_url='/login/'),],name='dispatch')

因為dispatch方法被 as_view() 中的 view() 調用,所以我們對這個方法添加裝飾器, 也就相當於對整個類視圖的方法添加裝飾器。

方法四:定義裝飾器時,添加一個self參數

裝飾器如下:

def my_decorator(func):
    # 此處增加了self
    def wrapper(self, request, *args, **kwargs): 
        print('自定義裝飾器被調用了')
        print('請求路徑%s' % request.path)
        # 此處增加了self
        return func(self, request, *args, **kwargs) 
    return wrapper

使用:直接用自定義裝飾器裝飾在函數視圖上

    @my_decorator
    def get(self, request):
        print('get方法')
        return HttpResponse('ok')

方法五:用Mixin擴展類的形式,繼承多個裝飾器,並為類視圖中的所有函數視圖添加裝飾行為

假設定義了兩個裝飾器@my_decorator和@my_decorator2

# 第一個擴展類, 讓他繼承自
object class BaseView(object): 
    @classmethod 
    def as_view(cls, *args, **kwargs): 
        view = super().as_view(*args, **kwargs) 
        view = my_decorator(view) 
        return view 
# 第二個擴展類,讓他繼承自object 
class Base2View(object): 
    @classmethod 
    def as_view(cls, *args, **kwargs): 
        view = super().as_view(*args, **kwargs) 
        view = my_decorator2(view) 
        return view 
# 類視圖, 讓他除了繼承自這兩個父類外, 最后繼承View類. 
class DemoView(BaseView, Base2View,View): 
    def get(self, request): 
        print('get方法') 
        return HttpResponse('ok') 
    def post(self, request): 
        print('post方法') 
        return HttpResponse('ok')

 第二種:定義類裝飾器,在函數,類中使用函數裝飾器

定義類裝飾器,在類中使用
class
ShowClassName(object): def __init__(self, cls): self._cls = cls def __call__(self, a): print('class name:', self._cls.__name__) print('a name:', a) print(self._cls) return self._cls(a) class Foobar(object): def __init__(self, a): self.value = a def fun(self): print(self.value) Foobar=ShowClassName(Foobar) Foobar('woshiceshi').fun() #跟下面的使用方式是一樣的 class ShowClassName(object): def __init__(self, cls): self._cls = cls def __call__(self, a): print('class name:', self._cls.__name__) print('a name:', a) print(self._cls) return self._cls(a) @ShowClassName class Foobar(object): def __init__(self, a): self.value = a def fun(self): print(self.value) a = Foobar('woshiceshi') a.fun()
定義類裝飾器,在函數中使用
class ShowClassName(object):
    def __init__(self, cls):
        self._cls = cls

    def __call__(self, a):
        print('class name:', self._cls.__name__)
        print('a name:', a)
        print(self._cls)
        return self._cls(a)


def func_ceshi(a):
    print(a)


func_ceshi=ShowClassName(func_ceshi)
func_ceshi('woshiceshi')

#跟下面的使用是一樣的

class ShowClassName(object):
    def __init__(self, cls):
        self._cls = cls

    def __call__(self, a):
        print('class name:', self._cls.__name__)
        print('a name:', a)
        print(self._cls)
        return self._cls(a)

@ShowClassName
def func_ceshi(a):
    print(a)


func_ceshi('woshiceshi')

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM