Using a variable as dictionary key in Django templates


So I ran into an interesting situation this weekend where I needed to use a variable as a dictionary key in a Django template. I had a dictionary and I wanted to iterate through it in order by key. Since the dictionary is an unordered data structure I created a list of the keys, sorted them, then iterated through the list using the iterator as the key for the dictionary.

d={"a":"apple", "b":"banana", "m":"mango", "e":"egg", "c":"carrot"}
ls = sorted(d)
print ls
for i in ls:
    print d[i]




This works great in python, but in django templates you can't use variables as a key for a dictionary. Here is an example of code in a template that DOESN'T WORK.

{% for i in ls %}
   {{ d.i }}
{% endfor %}


My solution was to come up with a custom template filter that allowed me to use the variable as a dictionary key. To create a template filter you first need to create a folder in your app called templatetags (don't forget the Then create a file where you will put your code. The name doesn't really matter but it will affect how we will import the template filter later so keep that in mind. I like the conventions and named mine


Next we need to write our template filter and register it to the template library. First we import the template module and create an instance of a template library so we can register our template filter.

from django import template
register = template.Library()

We then use a handy decorator to register our filter. If you use the name argument, you can give your filter a specific name, otherwise it will use the function name by default

def access(value, arg):
    return value[arg]

There we go, we're all done. We can now use the access filter on a dictionary in templates as long as we load dictionary_extras. A full example below.


from django import template
register = template.Library()

def access(value, arg):
    return value[arg]

context["d"] = {"a":"apple", "b":"banana", "m":"mango", "e":"egg", "c":"carrot"}
context["ls"] = sorted(d)

return context


{% load dictionary_extras %}

{% for key in ls %}
    {{ d|access:key }}
{% endfor %}