Solution 1 :

Better first convert to list of rows (using zip()) and send this to template

my_dict = {
    'id': [1, 2, 3, 4, 5],
    'product_name': ['product1', 'product2', 'product3', 'product4', 'product5'],
    'value': [200, 400, 600, 800, 1000],
    'available_qty': [1, 2, 3, 2, 4]
}

all_headers = list(my_dict.keys())

all_rows = list(zip(*my_dict.values()))

print(all_headers)
for row in all_rows:
    print(row)

Result:

['id', 'product_name', 'value', 'available_qty']
(1, 'product1', 200, 1)
(2, 'product2', 400, 2)
(3, 'product3', 600, 3)
(4, 'product4', 800, 2)
(5, 'product5', 1000, 4)

And then template could be (but I didn’t test it)

<h2>my dictionary</h2>

<table>

    <thead>
      <tr>
      {% for header in all_headers %}
        <th>{{ header }}</th>
      {% endfor %}
      <tr>
    </thead>
    
    <tbody>
      {% for row in all_rows %}
      <tr>
         {% for value in row %}   
            <td>{{ value }}</td>   
         {% endfor %}
      <tr>
      {% endfor %}
    </tbody>
    
</table>

EDIT:

If you use pandas then you could use df.to_html() to generate table

import pandas as pd

df = pd.DataFrame(my_dict)

html_table = df.to_html(index=False)

print(html_table)

and it gives HTML similar to code from my previous template

<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th>id</th>
      <th>product_name</th>
      <th>value</th>
      <th>available_qty</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>product1</td>
      <td>200</td>
      <td>1</td>
    </tr>
    <tr>
      <td>2</td>
      <td>product2</td>
      <td>400</td>
      <td>2</td>
    </tr>
    <tr>
      <td>3</td>
      <td>product3</td>
      <td>600</td>
      <td>3</td>
    </tr>
    <tr>
      <td>4</td>
      <td>product4</td>
      <td>800</td>
      <td>2</td>
    </tr>
    <tr>
      <td>5</td>
      <td>product5</td>
      <td>1000</td>
      <td>4</td>
    </tr>
  </tbody>
</table>

And you can send html_table to template and you have to display it with option safe (so it will not convert < > to &lg;, &gt;)

{{ html_table | safe }}

Solution 2 :

In your template

  • Load filters
{% load filter %}
{% block body %}
    <table class="table table-hover">
        <thead>
            <tr>
                {% for key in my_dict %}
                    <th scope="col">{{ key }}</th>
                {% endfor %}
            </tr>
        </thead>
        <tbody>
            {% for i in my_dict|RANGE %}
                <tr>
                    {% for key, value in my_dict.items %}
                        {% if forloop.counter0 < my_dict|length %}
                            <td>{{ value|items:i }}</td>
                        {% endif %}
                    {% endfor %}
                </tr>
            {% endfor %}
        </tbody>
    </table>
{% endblock %}

In project/app/ create a folder called templatetags

  • In your templatetags folder there will be
    • init.py
    • filters.py
  • put the following code in filters.py
from django import template

register = template.Library()


@register.filter
def RANGE(dictionary):
    length = 0
    for key, value in dictionary.items():
        if length < len(value):
            length = len(value)
    return list(range(length))


@register.filter
def items(List, index):
    return List[index]

Problem :

I’m currently working in a django project in which I do some data analysis using pandas library and want to display the data (which is converted into a dictionary) as a HTML table.

dictionary that I want to display:

my_dict = {
    'id': [1, 2, 3, 4, 5],
    'product_name': [product1, product2, product3, product4, product5],
    'value': [200, 400, 600, 800, 1000],
    'available_qty': [1, 2, 3, 2, 4]
}

I want to display the above dictionary like this table in django template.

id product_name value available_qty
1 product1 200 1
2 product2 400 2
3 product3 600 3
4 product4 800 2
5 product5 1000 4

I have tried the below code.

<table>
    <thead><h2><b>my dictionary</b></h2></thead>
        {% for key, values in my_dict.items %}
            <th><b>{{ key }}</b></th>
            {% for value in values %}   
                <tr>
                    {{value}}
                </tr>   
            {% endfor %}
        {% endfor %}
</table>

I get the results as,

HTML table result

(There is some space between each row displayed in the table)

Comments

Comment posted by furas

better first convert to

Comment posted by furas

I addes simpler version with

Comment posted by rangarajan

The to_html() method looks good and does everything I need. Thanks for this answer @furas it saves me a lot of time.

By