装饰类和类方法

2024-10-03 23:18:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我想在decorator中包装类的一个方法。如果有必要,我的类是基于django类的视图。你知道吗

第一种实现类型是wrap method bymethod\u decorator

class MyView(View):
   template_name = "index.html"
   @method_decorator(login_required):
   def dispatch(self, *args, **kwargs):
       return super(MyView, self).dispatch(*args, **kwargs)

好的,这个有用。但我不想每次都重写方法调度。你知道吗

第二种方式-混合和多重继承。你知道吗

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"

这也行。但是如果我想使用多个decorator,则需要列出parents中的所有mixin。这对我不太好。你知道吗

我想要下一个:

@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

但是在这个decorator中得到的cls不包含原始的classmethodsclassonlymethods。我想这是一个原因。你知道吗

如何将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'

Tags: nameindexreturndefhtmllogintemplatedecorator
1条回答
网友
1楼 · 发布于 2024-10-03 23:18:35

您可以安装django-braces。此库包含需要登录的mixin

from django.views.generic import View
from braces.views import LoginRequiredMixin


class SimpleView(LoginRequiredMixin, View):
    pass

对于正确的风格,你不需要为CBV装饰。如果您需要一些自定义视图权限,请在dispatch视图方法中实现您的逻辑。你知道吗

相关问题 更多 >