Using tuples (& dicts) in Django templates
UPDATE
Demonstrating the power of the web, and the great benefit to be had in publishing something even if it's not perfect, no sooner had I hit the send button than @stevejalim (of this parish) revealed to me that if you use a dict instead of a tuple, you can access the value by name, rather than index.
Thank you Steve.
Using tuples in Django template filters can cut down on extraneous filter functions and make your templates cleaner.
We have a fairly typical front-end templating pattern - we show a list of items, and each item in the list has a certain state which may affect the way in which it is displayed.
We use Django's template filters to return this kind of dedicated front-end information - e.g. if an object's state is 'in_progress', that might be converted to 'In progress' using the state_description filter:
from django.template import Library
register = Library()
@register.filter
def state_description(state):
if state == 'in_progress':
return 'In progress'
This can then be used in a template:
This object is "{{obj.state|state_description}}".
However, in reality it isn't just a description, it's a description, a pictogram, and a special colour, which means three separate filter functions:
def state_icon(state):
if state == 'in_progress':
return 'pb-thumbs-up'
def state_colour(state):
if state == 'in_progress':
return 'green'
def state_description(state):
if state == 'in_progress':
return 'In progress'
And a template which calls all three separate functions:
<li class="{{obj.state|state_icon}} {{obj.state|state_style}}">{{obj.state|state_description}}</li>
This is a fairly trivial example, but it would be cleaner if we returned all the information relating to the state property in one structure, which is where tuples come in. Combining these into one becomes:
def state_info(state):
if state == 'in_progress':
return ('pb-thumbs-up', 'green', 'In progress')
Now that we have our 3-tuple, we need to be able to access its elements, which we can do using the with
statement, and the .0
indexing format:
{% with obj.state|state_info as info %}
<li class="{{info.0}} {{info.1}}">{{info.2}}</li>
{% endwith %}
Making Freelance Work