如何创建一个适用于基于类的视图函数和类的装饰器?

时间:2018-04-02 12:40:02

标签: python django django-views

我有一些装饰器可以在基于类的视图之上使用,如下所示:

@method_decorator(auth0_login_required, name='dispatch')
class MyClass(DetailView):
    ...

我也希望能够在基于类的视图中的函数之上使用它,如下所示:

class MyClass2(DetailView):
    ...

    def get(self, request, *args, **kwargs): 
        ...

    @auth0_login_required
    def post(self, request, *args, **kwargs):
        ...

问题在于装饰器对这两个用例的工作方式并不相同,我想避免创建两个执行相同工作的装饰器。

这是装饰者的样子:

def auth0_login_required(function):
    def wrap(request, *args, **kwargs):
        if request.user.is_authenticated or request.user.is_staff:
            ...
        ...

        return function(request, *args, **kwargs)
    wrap.__doc__ = function.__doc__
    wrap.__name__ = function.__name__
    return wrap

对于第二个用例,我必须在self之前添加request作为参数。

我想知道是否有办法让它与一个装饰师一起工作?

1 个答案:

答案 0 :(得分:1)

您可以使用post修饰基于班级的视图的name='post'方法。

@method_decorator(auth0_login_required, name="post")
class MyClass2(DetailView):
    ...

    def get(self, request, *args, **kwargs): 
        ...

    def post(self, request, *args, **kwargs):
        ...

或者您可以直接装饰post方法。由于它是一种方法,您仍应使用method_decorator

class MyClass2(DetailView):
    ...

    def get(self, request, *args, **kwargs): 
        ...

    @method_decorator(auth0_login_required)
    def post(self, request, *args, **kwargs):
        ...

如果您有基于功能的视图,则不需要使用method_decorator

@auth0_login_required
def my_function_based_view(request, *args, **kwargs):