基于 django class 的视图会继承 method_decorators 吗?
Do django class based views inherit method_decorators?
我正在使用基于 django class 的视图。假设有一个这样的ListView:
@method_decorator(ensure_csrf_cookie, name='dispatch')
class SomeView(ListView):
...
如果另一个基于class的视图继承了SomeView,它是否也继承了"ensure_csrf_cookie"?或者它必须在每个 subclasses 上明确定义?
它必须在每个子classes 上明确定义。因为 method_decorator 只是函数并进行一些计算(这取决于你如何编写装饰器)然后它将调用你的 class SomeView。如果您继承了 SomeView,那么您必须为新 class 显式使用 method_decorator。可能会有帮助。
“@decorator”语法只是转换它的语法糖:
@decorator
class SomeClass(parent):
pass
进入这个:
class SomeClass(parent):
pass
SomeClass = decorator(SomeClass)
IOW,无论 decorator
做什么,都已完成 在 创建 class 之后,因此作为一般规则,您不能指望它被继承child classes of SomeClass
- "what the decorator did" 是否会被继承(或不继承)实际上取决于 "what the decorator did" 和 child class定义。
wrt/ 你的具体用例:method_decorator
用于修饰你的 class 的给定方法(你的示例中的 dispatch
方法)。如果您的 child class 没有覆盖此方法,那么它将在 parent class 上查找。在这种情况下,您最终确实会使用装饰方法。但是如果你在你的 subclass 中覆盖装饰方法,将使用新方法而不是 parent 的方法,所以它不会被自动装饰,你必须应用装饰器再次.
FWIW,自己测试很容易:
>>> def decorator(func):
... def wrapper(*args, **kw):
... print("before %s(%s, %s)" % (func, args, kw)
... )
... return func(*args, **kw)
... return wrapper
...
>>> from django.utils.decorators import method_decorator
>>> @method_decorator(decorator, name='foo')
... class Bar(object):
... def foo(self):
... print("%s.foo()" % self)
...
>>> b = Bar()
>>> b.foo()
before <function bound_func at 0x7fefab044050>((), {})
<Bar object at 0x7fefab09af10>.foo()
>>> class Quux(Bar): pass
...
>>> q = Quux()
>>> q.foo()
before <function bound_func at 0x7fefab044050>((), {})
<Quux object at 0x7fefab041110>.foo()
>>> class Baaz(Bar):
... def foo(self):
... print("this is Baaz.foo")
...
>>> bz = Baaz()
>>> bz.foo()
this is Baaz.foo
>>>
我正在使用基于 django class 的视图。假设有一个这样的ListView:
@method_decorator(ensure_csrf_cookie, name='dispatch')
class SomeView(ListView):
...
如果另一个基于class的视图继承了SomeView,它是否也继承了"ensure_csrf_cookie"?或者它必须在每个 subclasses 上明确定义?
它必须在每个子classes 上明确定义。因为 method_decorator 只是函数并进行一些计算(这取决于你如何编写装饰器)然后它将调用你的 class SomeView。如果您继承了 SomeView,那么您必须为新 class 显式使用 method_decorator。可能会有帮助。
“@decorator”语法只是转换它的语法糖:
@decorator
class SomeClass(parent):
pass
进入这个:
class SomeClass(parent):
pass
SomeClass = decorator(SomeClass)
IOW,无论 decorator
做什么,都已完成 在 创建 class 之后,因此作为一般规则,您不能指望它被继承child classes of SomeClass
- "what the decorator did" 是否会被继承(或不继承)实际上取决于 "what the decorator did" 和 child class定义。
wrt/ 你的具体用例:method_decorator
用于修饰你的 class 的给定方法(你的示例中的 dispatch
方法)。如果您的 child class 没有覆盖此方法,那么它将在 parent class 上查找。在这种情况下,您最终确实会使用装饰方法。但是如果你在你的 subclass 中覆盖装饰方法,将使用新方法而不是 parent 的方法,所以它不会被自动装饰,你必须应用装饰器再次.
FWIW,自己测试很容易:
>>> def decorator(func):
... def wrapper(*args, **kw):
... print("before %s(%s, %s)" % (func, args, kw)
... )
... return func(*args, **kw)
... return wrapper
...
>>> from django.utils.decorators import method_decorator
>>> @method_decorator(decorator, name='foo')
... class Bar(object):
... def foo(self):
... print("%s.foo()" % self)
...
>>> b = Bar()
>>> b.foo()
before <function bound_func at 0x7fefab044050>((), {})
<Bar object at 0x7fefab09af10>.foo()
>>> class Quux(Bar): pass
...
>>> q = Quux()
>>> q.foo()
before <function bound_func at 0x7fefab044050>((), {})
<Quux object at 0x7fefab041110>.foo()
>>> class Baaz(Bar):
... def foo(self):
... print("this is Baaz.foo")
...
>>> bz = Baaz()
>>> bz.foo()
this is Baaz.foo
>>>