首页 > 解决方案 > 如何使用多个参数制作自定义装饰器?

问题描述

在这里,我正在使用一些 kwargs 参数制作自定义装饰器,但装饰器无法正常工作。

错误:

TypeError: my_decorator() takes 1 positional argument but 2 were given

代码

def my_decorator(title, **data):

    def _method_wrapper(view_method):

        def _arguments_wrapper(request, *args, **kwargs) :
            obj = Model.objects.get(title=title)
            if obj.relatedmodel_set.filter(**data).exists():
                return view_method(request, *args, **kwargs)
            raise PermissionDenied

        return _arguments_wrapper

    return _method_wrapper

#view

@my_decorator('title', {'is_manager':True})
def my_view(request, id):

标签: djangodjango-views

解决方案


您使用**data,因此这意味着您可以传递命名参数,然后data是一个将字符串映射到相应项目的字典。

因此,您可以调用@my_decorator

@my_decorator('title', is_manager=True)
…

如果您希望能够传递位置参数,例如Q对象,您可以使用以下方式扩展签名:

def my_decorator(title, *data, **datb):
    def _method_wrapper(view_method):

        def _arguments_wrapper(request, *args, **kwargs) :
            obj = Model.objects.get(title=title)
            if obj.relatedmodel_set.filter(*data, **datb).exists():
                return view_method(request, *args, **kwargs)
            raise PermissionDenied

        return _arguments_wrapper

    return _method_wrapper

在这种情况下,您可以使用以下方法调用装饰器:

from django.db.models import Q

@my_decorator('title', Q(is_manager=True))
…

推荐阅读