我想在decorator中包装一个类的方法。如果有必要,我的课程是基于django类的视图。
第一种类型的实现是 method_decorator 的包装方法:
class MyView(View):
template_name = "index.html"
@method_decorator(login_required):
def dispatch(self, *args, **kwargs):
return super(MyView, self).dispatch(*args, **kwargs)
好的,这很有效。但我不想每次都覆盖方法 dispatch 。
第二种方式 - mixins和多重继承。
class LoginRequiredView(object):
@method_decorator(login_required):
def dispatch(self, *args, **kwargs):
return super(MyView, self).dispatch(*args, **kwargs)
class MyView(LoginRequiredView, View):
template_name = "index.html"
这也有效。但是如果我想使用多个装饰器,则需要在父级中列出所有mixins。这对我来说不是很好。
我想要下一个:
@viewdecorator(login_required)
class MyView(LoginRequiredView, View):
template_name = "index.html"
我的问题是如何实现 viewdecorator 。我试着写这个:
def viewdecorator(decorator):
def wrap(cls):
dispatch = getattr(cls, 'dispatch', None)
if dispatch:
setattr(cls, 'dispatch', method_decorator(decorator))
return cls
return wrap
但是这个装饰器中产生的cls不包含原始的 classmethods 和 classonlymethods 。我猜这种行为的原因。
如何将 viewdecorator 写入 classmethods 将在结果cls中显示?
UPD:我理解了这项工作以及实际工作代码如下所示
def viewdecorator(decorator):
def wrap(cls):
getattribute = cls.__getattribute__
def newgetattr(cls, name):
attr = getattribute(cls, name)
if name == 'dispatch':
return decorator(method_decorator(attr))
return attr
cls.__getattribute__ = newgetattr
return cls
return wrap
@viewdecorator(login_required)
@viewdecorator(csrf_exempt)
class EntriesMyList(EntriesList):
template_name = 'index.html'
答案 0 :(得分:0)
您可以安装django-braces。该库包含登录所需的mixin
from django.views.generic import View
from braces.views import LoginRequiredMixin
class SimpleView(LoginRequiredMixin, View):
pass
对于正确的款式,您不需要CBV装饰器。如果您需要一些自定义视图权限,请在dispatch
视图方法中实现逻辑。