Possible to use decorators in django to do permissions based on a view parameter?

decorator, django, permissions

Solution

The decorator has access to all the view arguments, so it's definitely possible. You could do this:

def group_required(arg_name):
    def decorator(view):
        def wrapper(request, *args, **kwargs):
            group_id = kwargs.get(arg_name)
            user = request.user
            if group_id in user.groups.values_list('id', flat=True):
                return view(request, *args, **kwargs)
            else:
                return HttpResponseForbidden # 403 Forbidden is better than 404
        return wrapper
    return decorator

(If you don't need the flexibility of dynamically defining the argument in the decorator, eg if you always call it `group_id`, you can miss out the outer function here and just use `kwargs.get('group_id')`.)

Problem

I'm not sure it's possible, but is there a way to write something like ``` @group_required('group_id') def myview(request, group_id): ..... ``` Where I look at the value of the parameter group_id and limit access to this view to only people who are in this group? I know it is possible to create a decorator to check membership in some specific group ``` @group_required('admin') def myview(request): .... ``` But say I want a view that is only accessible to people within a certain group, which is determined by the url. So for example ``` /group/1 /group/2 ``` Should each have permissions so that only members of group #X can see that page. I can easily write this functionality within the view ``` group = get group if user not in group raise 404 ``` but that logic is repeated all over. Decorators seems like a promising way to do it, but it seems the scope is backwards. Is there another preferred way to handle this sort of permissions? Thanks!

Original source

Related problems