is_authenticated() vs. is_anonymous()

A warning for those who might not of noticed the change. About a month ago (in [3360]), an is_authenticated method was added to the User and AnonymousUser classes. These are the classes used for Django's default authentication system.

Previously, the template code used for displaying content based on whether or not a user had authenticated went something like:

{% if not user.is_anonymous %}
Content for logged in users.
{% else %}
Content for non-logged in users.
{% endif %}

The problem with this code is that if, somehow, the user template variable did not get populated, your template would treat the requesting user as if they were logged in.

Notice that this sort of behavior will be seen for all negative if statements. The template code {% if not variable %} will always evaluate to True if variable doesn't exist in the context. This is because Django uses the settings.TEMPLATE_STRING_IF_INVALID value for non-existent template variables; by default, TEMPLATE_STRING_IF_INVALID is '', which evaluates to False (and not False is True).

Notice also that even using the template code:

{% if user.is_anonymous %}
Content for non-logged in users.
{% else %}
Content for logged in users.
{% endif %}

(without the not) will not work in this case because if the user variable is non-existent, the requesting user will still be treated as if they were authenticated.

The new, recommended way for checking that a requesting user has been authenticated in your templates is:

{% if user.is_authenticated %}
Content for logged in users.
{% else %}
Content for non-logged in users
{% endif %}

Here, if the user template variable were to not exist, your template would treat the requesting user as non-authenticated, just as we would want.