使用额外参数创建通用视图装饰器

Posted

技术标签:

【中文标题】使用额外参数创建通用视图装饰器【英文标题】:Creating generic view decorator with an extra parameter 【发布时间】:2018-11-01 05:55:08 【问题描述】:

在尝试创建装饰器来包装我的应用程序视图时,我无法将参数传递给我的装饰器。 我的观点目前是这样的:

@api_view(['GET', 'POST'])
@permission_classes((IsAuthenticated,))
def some_view(request):

问题是,除了请求之外,我还想将一个额外的参数传递给我的通用视图。 我试过这个:

@api_view(['GET', 'POST'])
@permission_classes((IsAuthenticated,))
@generic_view("some argument")
def some_view(request):

使用这个 generic_view:

def generic_view(argument):
    def _method_wrapper(func):
        def decorator(request, *args, **kwargs):
            some_function(argument)
            data = func(request)
            return Response(data, status=200)
        return decorator
    return _method_wrapper

问题是参数没有通过。我寻找它和论点,args 和 kwargs,它只是没有通过。 顺便说一句,我使用的是 django 1.8,python 2.7。

【问题讨论】:

我真的不明白问题出在哪里。什么不工作? 你最好做的唯一一件事就是将*args**kwargs 也传递给func,并使用@wraps 装饰器。但除此之外,它应该可以工作。 万一出现问题,您可以发布回溯(或至少相关部分)吗? 您确定您已通过身份验证吗?由于这些装饰器首先完成,因此它将首先执行过滤。只有在它是 GET 或 POST 并且permission_classes 接受请求的情况下,它才会向下传递一个级别。 我是。我刚刚编辑了帖子。我想通过的论点没有通过 【参考方案1】:

这可以通过lambda 函数来实现

decorator_with_arguments = lambda decorator: lambda *args, **kwargs:lambda func: decorator(func, *args, **kwargs) 

现在你用这个装饰器包装你的函数。以下将起作用:

@decorator_with_arguments
def generic_view(function,arg):
    def _method(request, *args, **kwargs):
        print(arg) # print arg : Python 2.*
        # data = func(request)
        return function(request, *args, **kwargs)
    return _method

现在你可以在你的views中使用generic_view作为@decorator

@generic_view("some argument")
def some_view(request):
    pass

# output
>>> 'some argument'

【讨论】:

对不起。它不起作用。当我调试它并检查 arg 值时,我得到 NameError: name 'arg' is not defined 我认为它可能与多个装饰器有关? (api_view & permission_classes) 这是一个例子,尝试print()你已经传递的参数。在你的情况下,它是 argument 而不是 arg NameError: name 'arg' is not defined 实际上 你没有 arg 作为参数。看看我上面的答案,你可以看到我的论点名为 arg generic_view(function,arg):,这就是我输入print arg 的原因,对于你的情况,它是generic_view(argument):,你应该使用print argument。 **不要忘记添加function作为第一个参数..或者简单,只需复制粘贴我的代码 我没有提到,但我当然把它改成了arg。 请让我看看你的装饰器代码中有什么

以上是关于使用额外参数创建通用视图装饰器的主要内容,如果未能解决你的问题,请参考以下文章

Python装饰器通用样式

如何在vue.js 2应用程序中全局使用自定义装饰器?

Python进阶装饰器(Decorator)

Python装饰器

Angular - 创建通用装饰器包装 @HostListener

装饰器