Django: Custom Decorator with an Argument

Sometimes you want to be able to create a decorator for functions in Django but have the ability to pass in an argument into the decorator. I came across this when I wanted to switch from the require_login decorator to check if a user was in a certain group to see the function.

So the first thing I did was create a new directory in my project root called decorators and put a blank __init__.py file there. My I cated an auth.py file with the following contents.

from functools import wraps

from django.contrib.auth.models import Group
from django.http import Http404

def group_required(groups=[]):    
    def decorator(func):
        def inner_decorator(request,*args, **kwargs):
            for group in groups:
                try:
                    if Group.objects.get(name=group) in request.user.groups.all():
                        return func(request, *args, **kwargs)
                except:
                    pass

            raise Http404()

        return wraps(func)(inner_decorator)

    return decorator

So we can use it like this in our project


from decorators.auth import group_required

@group_required(["admins"])
def show_index(request):
    ....

I decided to make it a list being passed in. The main reason was to make it was to pass in multiple groups that you might want to allow to be allowed in.

My version doesn’t do much error checking.. if you want a more updated version of this function checkout my githib project I’ve started to put all my custom decorators up and online

http://github.com/mzupan/django-decorators

What Rollout will be?

I have been debating just helping with fabric or writing my own app for a week now and I just think what I need and want fabric just isn’t and too much work to get it to the way I want it to be.

So here are some of the things I want Rollout to be.

  1. Be able to run in console
  2. Be able to tie the Rollout API into your own python webapp
  3. Rollout output should be multiformat (xml/json)
  4. Should be threaded
  5. Should have a run_first() and run_last() method
  6. Tie in git/svn?

Again if you want to watch the project it is http://github.com/mzupan/rollout

Reason #2 on why Django is great

The decorators that Django has are a great time saver. There are a lot of methods in your views where you only want logged in users to see. So you can use a decorator before the function to check if they are logged in or not.

from django.contrib.auth.decorators import login_required

@login_required
def my_view(request):
    ....

So learn to use these time savers in your project.

« Previous Page