Django Template Variable or Else

2016-03-09T15:31:35.797173-06:00 2016-03-09T15:33:10.937297-06:00

Here is one of those little things you pick up when using Django that is easy to miss.  Sadly it took years before I found this particular gem of a technique.  I noticed several clients over the last few months that didn't know about it so I thought I would share. 

The Situation

You've got a spot in your Django Template where you want to show the value contained in a context variable (or possibly several) and if none of them exist you want to show some value.  

Let's pretend we have a simple Django project where users may have a role associated with them.  If they do, we want to display the text contained in the role's name.  If they do not have an associated role, we want to display the string 'Regular User'.  

Our template receives as part of its context the list of all users as 'users' and 'role' is a OneToOneField back to the User object.

The naive solution

The way that comes to mind for this type of situation is to use an if test in the template like this:

<ul>
{% for u in users %}
    <li>
        {{ u.username }} 
        {% if u.role %} 
            {{ u.role.name }} 
        {% else %} 
            Regular User 
        {% endif %}
     </li>
{% endfor %}
</ul>

but as you have probably guessed there is an easier way! The easier way is to use the firstof filter to help. The secret sauce here is that the values given to firstof do not have to be context variables, they can be simple strings.  So instead of that big if above we can do:

<ul>
{% for u in users %}
    <li>{{ u.username }} {% firstof u.role.name 'Regular User' %}</li>
{% endfor %}
</ul>

This is so much more concise, easier to write, and much easier to decipher when your co-worker comes along to make changes to this template. 

Keep this in mind the next time you're littering your Django template with if else trees all over the place, you might be able to make things easier with firstof! 

Hope this helps!