« Back to blog

Authentication in Django templates

I recently came across a problem when adding user accounts to a Django application I'm currently working on: I wanted to access information about the current user, e.g. whether they were anonymous or logged in, so that I could display a login message or a link to their homepage respectively. This sounds like a relatively simple thing to accomplish but the problem was that I didn't want to have to look up the current user's information in every view method and pass it to the template. Luckily Django provides a way of dealing with this very situation by providing a special template 'context'. From the Django documentation:

A context is a "variable name" -> "variable value" mapping that is passed to a template.

The special context here is called DjangoContext (no great shock there) and it provides a few new variables to the template (again from the official documentation):

  • user -- An auth.User instance representing the currently logged-in user (or an AnonymousUser instance, if the client isn't logged in). See the user authentication docs.
  • messages -- A list of auth.Message objects for the currently logged-in user.
  • perms -- An instance of django.core.extensions.PermWrapper, representing the permissions that the currently logged-in user has. See the permissions docs.

To use DjangoContext start by importing it using the following line at the top of your views.py file:

from django.core.extensions import DjangoContext

It was at this point that the problem arose: the documentation is fairly cryptic about exactly how the context object should be used when building a template. It was even more confusing because I am not using the standard method of rendering a template which involves 1) loading a template, 2) creating a context object, and 3) rendering the template using the render() method of the template. Instead I'm using render_to_response again from django.core.extensions. This function takes the template name and list of template variables as a dict and does all the work for you in one line. Nice. But how do I take advantage of the DjangoContext context which provides all that lovely user information while still using render_to_response too keep my code nice and clean? Like this:

return render_to_response('template_name', {'var1': var1, 'var2': var2}, context_instance=DjangoContext(request))

This renders the template template_name, passing it the variables var1 and var2 but also tells Django to use the new context instance DjangoContext. In the template could then check if the user was logged in with:

{% if user.is_anonymous %}

Simple!