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.
you can now replace render_to_response() with render() http://dev.taherh.org/2012/06/05/django-view-shortcuts
Posted on July 23, 2012 at 7:46 pm.
Markus,
Thanks for pointing that out! Updated the post =)
Posted on July 24, 2012 at 1:00 am.
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
Posted on July 24, 2012 at 9:10 am.
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!
Posted on July 24, 2012 at 11:54 am.