Iterating Through a Dictionary in a Dictionary in Django Templates

Django templates provide several useful filters and tags for looping through and accessing data in dictionaries and lists. However, iterating through nested data structures like a dictionary inside a dictionary can be tricky. In this post, I’ll explain different methods for looping through and accessing nested dictionary’s data in Django templates.

Using Dot Notation in Dictionary

The simplest way to access nested dictionary data is to use dot notation. For example, if your context data passed to the template contains:

data = {
  "categories": {
    "sports": ["football", "basketball"],
    "entertainment": ["music", "movies"]
  }
}

You can access the list values like:

{{ data.categories.sports }}
{{ data.categories.entertainment }} 

This prints the lists inside each dictionary’s key. However, it doesn’t allow you to iterate through and print each list item. For that, you need to use Django template tags and filters.

Looping With for tag

Django’s for tag lets you loop through list and dictionary data. To loop through the dictionary’s from the example above and access the list values, do:

{% for category, values in data.categories.items %}
  <h3>{{ category }}</h3>
  <ul>
    {% for value in values %}
      <li>{{ value }}</li> 
    {% endfor %}
  </ul>
{% endfor %}

This loops through each dictionary’s key/value pair, prints the key name in a heading, and iterates through the list to print each item. The end result prints:

<h3>sports</h3>
<ul>
  <li>football</li>
  <li>basketball</li>
</ul>

<h3>entertainment</h3> 
<ul>
  <li>music</li>
  <li>movies</li>  
</ul>

Accessing Dictionary Values in Lists

You can also loop through lists of dictionaries. For example:

data = {
  "categories": [
    {"name": "sports", "items": ["football", "basketball"]},
    {"name": "entertainment", "items": ["music", "movies"]}
  ]
}

To iterate through this in the template:

{% for category in data.categories %}
  <h3>{{ category.name }}</h3>
  <ul>
    {% for item in category.items %}
      <li>{{ item }}</li>
    {% endfor %}
  </ul>
{% endfor %}

This loops through each dictionary inside the list and prints out the values.

Using Custom Template Tags

For complex nested data, you can create custom template tags to encapsulate the logic. For example:

templatetags/data_tags.py

from django import template

register = template.Library() 

@register.simple_tag 
def print_category(data):
  html = ''

  for category in data:
    html += f'<h3>{category["name"]}</h3>'

    html += '<ul>'

    for item in category["items"]:  
      html += f'<li>{item}</li>'

    html += '</ul>'

  return html

You can then simplify the template code to:

{% load data_tags %}

{% print_category data.categories %}

This keeps your templates clean and reusable.

In summary, Django‘s template system provides many ways to access and iterate through dictionary’s data – even nested dictionaries. Using dot notation, the for tag, and custom template tags allows you to loop through and print nested dictionary content in flexible ways. With some practice, these methods can help reduce template complexity for dynamic web applications.