【Django】在视图类使用装饰器的几种方式

版权声明:欢迎交流,转载请注明出处。 https://blog.csdn.net/u013034226/article/details/83958655

在Django中,视图中的类称为类视图,个人喜欢把视图中的类叫做视图类,函数叫做视图函数,一种习惯而已。

一、定义视图类

定义类视图,且类视图继承自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):

因为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')

个人感觉,不是说哪种方法有什么优劣之分,看你对规范,易读,易维护,扩展性等的要求,选择最合适的一个。

猜你喜欢

转载自blog.csdn.net/u013034226/article/details/83958655