7

I have the following decorator and view which works fine.

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

View

@event_admin_only
def event_dashboard(request, event_slug):
    pass

But how can I modify my decorator such that it takes in an additional parameter like so:

@event_admin_only(obj1,[...])
def event_dashboard(request, event_slug):
    pass
martijnn2008
  • 3,406
  • 5
  • 29
  • 39
super9
  • 27,683
  • 38
  • 115
  • 170
  • 1
    possible duplicate of [How to create a Python decorator that can be used either with or without parameters?](http://stackoverflow.com/questions/653368/how-to-create-a-python-decorator-that-can-be-used-either-with-or-without-paramet) – DrTyrsa Jan 27 '12 at 07:47

1 Answers1

19

You need to wrap the decorator function creation in another function:

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

This can then be called like this:

@the_decorator("an_argument", "another_argument")
def event_dashboard(request, event_slug):

I'd recommend the answer from e-satis on this question to understand this: How to make a chain of function decorators?

David Neale
  • 15,810
  • 5
  • 57
  • 84