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
The decorator arguments are accessible to the inner decorator through a closure, exactly like how the wrapped() inner function can access f . And since closures extend to all the levels of inner functions, arg is also accessible from within wrapped() if necessary.
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With