【问题标题】:Do django class based views inherit method_decorators?django 基于类的视图是否继承 method_decorators?
【发布时间】:2019-07-30 08:01:17
【问题描述】:

我正在使用基于 django 类的视图。假设有一个这样的 ListView:

@method_decorator(ensure_csrf_cookie, name='dispatch')
class SomeView(ListView):
    ...     

如果另一个基于类的视图继承了SomeView,它是否也继承了“ensure_csrf_cookie”?还是必须在每个子类上明确定义?

【问题讨论】:

    标签: django inheritance decorator django-class-based-views csrf-token


    【解决方案1】:

    “@decorator”语法只是将其转换的语法糖:

    @decorator
    class SomeClass(parent):
        pass
    

    进入这个:

    class SomeClass(parent):
        pass
    
    SomeClass = decorator(SomeClass)
    

    IOW,无论decorator 做什么都是在创建类之后完成的,所以作为一般规则,你不能指望它被SomeClass 的子类继承——无论“什么装饰器做了”实际上会被继承(或不被继承)实际上取决于“装饰器做了什么”和子类定义。

    wrt/ 您的具体用例:method_decorator 用于装饰您的类的给定方法(您的示例中的 dispatch 方法)。如果您的子类没有覆盖此方法,那么它将在父类中查找。在这种情况下,您确实最终会使用装饰方法。但是如果你在你的子类中重写了修饰的方法,新的方法将被使用而不是父类的方法,所以它不会被自动修饰,你必须再次应用修饰器。

    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
    >>> 
    

    【讨论】:

      【解决方案2】:

      必须在每个子类上明确定义。因为method_decorator只是一个函数并且做一些计算(它取决于你如何编写你的装饰器)然后它会调用你的类SomeView。如果您继承 SomeView 那么您必须为该新类显式使用 method_decorator。这可能会有所帮助。

      【讨论】:

      • @HsnVahedi 唉,这个答案是不准确的——它取决于装饰器的作用和你如何定义你的子类之间的一些交互。
      猜你喜欢
      • 1970-01-01
      • 2012-10-27
      • 2015-12-04
      • 2020-10-09
      • 1970-01-01
      • 2019-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多