在 Django 中,当使用基于类的视图(Class-Based Views, CBVs)时,添加装饰器的方式与函数式视图(Function-Based Views, FBVs)有所不同。由于 CBVs 是类而不是函数,你不能直接像 FBVs 那样使用装饰器。但是,Django 提供了几种方法来给 CBVs 添加装饰器。
方法一:使用 method_decorator
装饰器
Django 提供了一个 method_decorator
装饰器,它可以用于装饰类中的方法。你可以将它应用于类的方法上,或者作为类的元类参数来装饰类的所有方法或特定方法。
装饰单个方法
from django.utils.decorators import method_decorator
from django.views.decorators.http import require_http_methods
class MyView(View):
@method_decorator(require_http_methods(["GET", "POST"]))
def dispatch(self, request, *args, **kwargs):
# 这里的 dispatch 方法是类视图的入口点,
# 装饰它会影响所有 HTTP 方法
return super().dispatch(request, *args, **kwargs)
def get(self, request, *args, **kwargs):
# 处理 GET 请求
pass
def post(self, request, *args, **kwargs):
# 处理 POST 请求
pass
注意,dispatch
方法是类视图的入口点,装饰它会影响所有 HTTP 方法。如果你只想装饰特定的方法(如 get
或 post
),你可以直接在那些方法上使用 method_decorator
,但需要将 name
参数设置为 'get'
或 'post'
(取决于你要装饰的方法),并作为类的一个内部方法调用它。
装饰特定方法
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page
class MyView(View):
@method_decorator(cache_page(60 * 15)) # 缓存 15 分钟
def get(self, request, *args, **kwargs):
# 只有 GET 请求会被缓存
pass
def post(self, request, *args, **kwargs):
# POST 请求不会被缓存
pass
方法二:使用 @method_decorator
作为类装饰器
如果你想要装饰类中的所有方法,但不想修改 dispatch
方法,你可以将 @method_decorator
作为类装饰器使用,并指定 name
参数为 '__init__'
(尽管这通常不是必需的,因为直接装饰类的方法更常见)。但更常见的是,你会直接在方法上使用它,如上例所示。
方法三:使用 decorator_from_middleware
虽然这不是直接给 CBV 添加装饰器的标准方法,但 Django 的 decorator_from_middleware
可以将中间件转换为装饰器。这在某些高级用例中可能很有用,但通常不是给 CBV 添加装饰器的首选方法。
结论
通常,你会使用 method_decorator
来给 CBV 的方法添加装饰器。记住,装饰 dispatch
方法会影响所有 HTTP 方法,而直接装饰特定方法(如 get
或 post
)则只会影响那些方法。