Django leverages Python’s ability to use decorators extensively. Decorators in Python are defined as:

A Python decorator is a specific change to the Python syntax that allows us to more conveniently alter functions and methods.

In layman’s terms, decorators allow us to dynamically alter functions without having to actually change the function itself. Sounds pretty neat? Well, you can read more about Python Decorators here and here.

The most common use of a decorator is the infamous login_required. This decorator is used in conjunction with a view that restricts access to authenticated users only.

from django.contrib.auth.decorators import login_required
from django.shortcuts import render

@login_required
def my_view(request):
    return render(request, 'template.html')

This decorator is very useful, because I don’t have to actually change anything about my view to restrict access to it. However, what if you want to restrict a view to only authenticated users who are currently active? This can easily be accomplished with a custom decorator:

Thanks to the user_passes_test decorator that comes with Django, we can chain this together with the login_required to create our custom decorator.

To break it down further, we pass an anonymous function into the user_passes_test decorator that returns the value of is_active, which is a boolean that designates if the user is active. Next we set the login_url parameter, which will redirect to this URL if the user is not active. For further reference, check out the actual source for user_passes_test.

Now we just update our view to incorporate our new, reusable decorator.py package and decorator.

from django.shortcuts import render

from myapp.decorators import active_and_login_required

@active_and_login_required
def my_view(request):
    return render(request, 'template.html')

4 Comments on “Create a custom authentication decorator in Django”

You can track this conversation through its atom feed.

  1. Markus Gattol says:

    you can now replace render_to_response() with render() http://dev.taherh.org/2012/06/05/django-view-shortcuts

  2. Dan says:

    Markus,

    Thanks for pointing that out! Updated the post =)

  3. Markus Gattol says:

    Dan, with your example you can now simply write

    return render(request, ‘template.html’)

    instead of

    return render_to_response(‘template.html’, {}, context_instance=RequestContext(request))

    have a look at https://docs.djangoproject.com/en/dev/topics/http/shortcuts/#render :)

  4. Dan says:

    Markus,

    My mistake, I appreciate the second correction! I was in a rush last night and made the change without realizing that the default parameters were different between the two shortcuts. Thanks again!

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>