Django为decorator添加了可选参数

sup*_*er9 4 python django decorator

我有以下装饰和视图哪个工作正常.

装饰

def event_admin_only(func):
    """
    Checks if the current role for the user is an Event Admin or not
    """
    def decorator(request, *args, **kwargs):
        event = get_object_or_404(Event, slug=kwargs['event_slug'])

        allowed_roles = [role[1] for role in Role.ADMIN_ROLES]

        # get user current role
        current_role = request.session.get('current_role')

        if current_role not in allowed_roles:
            url = reverse('no_perms')
            return redirect(url)
        else:       
            return func(request, *args, **kwargs)
    return decorator
Run Code Online (Sandbox Code Playgroud)

视图

@event_admin_only
def event_dashboard(request, event_slug):
    pass
Run Code Online (Sandbox Code Playgroud)

但是我如何修改我的装饰器,以便它接受一个额外的参数,如下所示:

@event_admin_only(obj1,[...])
def event_dashboard(request, event_slug):
    pass
Run Code Online (Sandbox Code Playgroud)

Dav*_*ale 11

您需要将装饰器函数创建包装在另一个函数中:

def the_decorator(arg1, arg2):

    def _method_wrapper(view_method):

        def _arguments_wrapper(request, *args, **kwargs) :
            """
            Wrapper with arguments to invoke the method
            """

            #do something with arg1 and arg2

            return view_method(request, *args, **kwargs)

        return _arguments_wrapper

    return _method_wrapper
Run Code Online (Sandbox Code Playgroud)

然后可以这样调用:

@the_decorator("an_argument", "another_argument")
def event_dashboard(request, event_slug):
Run Code Online (Sandbox Code Playgroud)

我强烈推荐e-satisf对这个问题的回答来理解这个问题:如何建立一系列功能装饰器?