I set up my Django project to use MySQL, so that I could use a list in a JSONField. Little did I know that accessing elements of that list by their index would be another problem entirely. There are two confounding things. First, in Jinja2, you can access a for-loop index with the loop.index
or loop.index0
keywords, but in a Django project, you need to use forloop.counter
or forloop.counter0`. The trailing zero on those keywords specify a zero-indexed counter rather than a one-indexed counter. The second thing is that you need to provide a custom template tag in order to cleanly access elements in a JSONField list by their index.
The first item is easy enough: when you’re using Django, use for loop.counter0 instead of the builtin Jinja2 loop.index0. The second item requires more work. First, create a package named templatetags
in the same directory in your app as your models.py
and views.py
; “creating a package” in this sense just means creating a new directory called templatetags
, and placing an empty __init__.py
file in it. Next, in the templatetags
directory, add a file named index.py
from django import template register = template.Library() @register.filter def index(List, i): return List[int(i)]
Now, in your template, you can say,
{% load index %} ... {% for some_other_thing in some_list %} {{ model.list_of_items | index:forloop.counter0 }} {% endfor %}
To get this to work as expected, you’ll have to restart the server if it’s running.