两种装饰基于类的视图的方法有什么区别?

时间:2012-08-26 18:33:30

标签: django django-views

我正在编写一个继承自ListView的视图,并尝试将视图限制为登录用户。

https://docs.djangoproject.com/en/dev/topics/class-based-views/#decorating-in-urlconf说在URLconf中使用login_required进行装饰“在每个实例的基础上应用装饰器。如果你想要对每个视图实例进行装饰,你需要采取不同的方法” - 这种方法用来装饰视图代码中的调度方法。

我以为我知道一个类和一个实例之间的区别,但这个短语对我来说没有任何意义。有人可以澄清吗?除了在URLconf中有一个装饰器而不是在类定义中,这两种方法有什么区别?

该链接上面的段落似乎回答了这样一个问题:“由于基于类的视图不是函数,因此根据您是使用as_view还是创建子类,装饰它们的工作方式会有所不同。”

真的?我似乎能够使用URLconf方法和我的ListView子类。

1 个答案:

答案 0 :(得分:5)

想象一下,您有以下基于类的视图:

class PostListView(ListView):
     model = Post

ProtectedPostListView = login_required(PostListView.as_view())

和你的urls.py:

url(r'posts$', ProtectedPostListView)

如果您使用此方法,则会失去继承ProtectedPostListView的能力,例如

class MyNewView(ProtectedPostListView):
    #IMPOSSIBLE

这是因为.as_view()返回一个函数,在应用login_required装饰器之后你会留下一个函数,所以不能进行子类化。

另一方面,如果你采用第二种方法,即使用方法装饰器,子类化是可能的。 e.g

class PostListView(ListView):
     model = Post

     @method_decorator(login_required)
     def dispatch(self, *args, **kwargs):
         return super(PostListView, self).dispatch(*args, **kwargs)

class MyNewView(PostListView):
     #LEGAL