Search code examples
pythonhtmldjangodjango-templatesnested-loops

Django template render a nested dict with tuples


Here's my dict =

{
'123': {'metric_1': [('url_1', 'caption_1'), ('url_2', 'caption_2'), ('url_3', 'caption_3'), ('url_4', 'caption_4')], 'metric_2': [('url_1', 'caption_1'), ('url_2', 'caption_2'), ('url_3', 'caption_3'), ('url_4', 'caption_4')]}, 
'456': {'metric_1': [('url_1', 'caption_1'), ('url_2', 'caption_2'), ('url_3', 'caption_3'), ('url_4', 'caption_4')], 'metric_2': [('url_1', 'caption_1'), ('url_2', 'caption_2'), ('url_3', 'caption_3'), ('url_4', 'caption_4')]},
'789': {'metric_1': [('url_1', 'caption_1'), ('url_2', 'caption_2'), ('url_3', 'caption_3'), ('url_4', 'caption_4')], 'metric_2': [('url_1', 'caption_1'), ('url_2', 'caption_2'), ('url_3', 'caption_3'), ('url_4', 'caption_4')]}, 
}

it basically is a dict of a dict of a list of tuples.

what I'd like to render via Django template is:

123
metric_1
url_1        url_2        url_3       url_4
caption_1    caption_2    caption_3   caption_4

metric_2
url_1        url_2        url_3       url_4
caption_1    caption_2    caption_3   caption_4


456
metric_1
url_1        url_2        url_3       url_4
caption_1    caption_2    caption_3   caption_4

metric_2
url_1        url_2        url_3       url_4
caption_1    caption_2    caption_3   caption_4


789
metric_1
url_1        url_2        url_3       url_4
caption_1    caption_2    caption_3   caption_4

metric_2
url_1        url_2        url_3       url_4
caption_1    caption_2    caption_3   caption_4

but I'm not able to do so, here's my current Django template:

<div class="grid grid-cols-2 gap-2 p-2">
{% for one_analysis_id, all_metrics in url_dict.items %}
<table>
    <tr><p>Analysis ID: {{ one_analysis_id }}</p></tr>
    {% for metric_name, url_and_caption_tuple_list in all_metrics.items %}
        <tr><p>{{ metric_name }}</p></tr>
        <tr>
        {% for url_and_caption_tuple in url_and_caption_tuple_list %}
            <td><img width="350" height="300" src="{{ url_and_caption_tuple.0 }}"><div>{{ url_and_caption_tuple.1 }}</div></td>
        {% endfor %}
        </tr>
    {% endfor %}
</table>
{% endfor %}
</div>

What the above code renders is:

123
metric_1
metric_2
url_1        url_2        url_3       url_4
caption_1    caption_2    caption_3   caption_4

url_1        url_2        url_3       url_4
caption_1    caption_2    caption_3   caption_4


456
metric_1
metric_2
url_1        url_2        url_3       url_4
caption_1    caption_2    caption_3   caption_4

url_1        url_2        url_3       url_4
caption_1    caption_2    caption_3   caption_4


789
metric_1
metric_2
url_1        url_2        url_3       url_4
caption_1    caption_2    caption_3   caption_4

url_1        url_2        url_3       url_4
caption_1    caption_2    caption_3   caption_4

Could anyone please provide any insight?

Thanks!


Solution

  • I am not promoting this way of doing it, but it is a working solution:

    <div class="grid grid-cols-2 gap-2 p-2">
      {% for one_analysis_id, all_metrics in url_dict.items %}
      <table class="table">
        <tr><th>Analysis ID: {{ one_analysis_id }}</th></tr>
        {% for metric_name, url_and_caption_tuple_list in all_metrics.items %}
        <tr><th>{{ metric_name }}</th></tr>
        <tr>
          {% for url_and_caption_tuple in url_and_caption_tuple_list %}
          <td>{{ url_and_caption_tuple.0 }}</td>
          {% endfor %}
        </tr>
        <tr>
          {% for url_and_caption_tuple in url_and_caption_tuple_list %}
          <td>{{ url_and_caption_tuple.1 }}</td>
          {% endfor %}
        </tr>
        {% endfor %}
      </table>
      {% endfor %}
    </div>
    

    As I said already in the comments, this would better be handled inside of the view's logic and be passed to the template in an easily digestible format.