How to structure data to easily build HTML tables in Flask


Question

I am trying to create HTML tables from data stored in a table. My data is read from a table and converted into a dict of lists, e.g.:

x = {'date':[u'2012-06-28', u'2012-06-29', u'2012-06-30'], 'users': [405, 368, 119]}

My goal is to create an HTML table with the following structure for an arbitrary list length:

<table>
  <thead>
    <th>Date</th>
    <th>Users</th>
  </thead>

  <tbody>      
    <tr>
      <td>2012-06-28</td>
      <td>405</td>
    </tr>
    <tr>
      <td>2012-06-29</td>
      <td>368</td>
    </tr>
    <tr>
      <td>2012-06-30</td>
      <td>119</td>
    </tr>
  </tbody>
</table> 

I have tried doing this two incorrect ways in my Flask template:

<tbody>
  {% for line in x %}
    <tr>
      <td>{{ x.date|tojson|safe }}</td>
      <td>{{ x.users }}</td>
     </tr>
   {% endfor %}
</tbody>

Which prints the entire list into each column.

And:

{% for date in x.date %}
  <tr><td>{{ date|tojson|safe }}</td></tr>
{% endfor %}

{% for users in x.users %}
  <tr><td>{{ users }}</td></tr>
{% endfor %}

Which simply prints everything into the first column.

These experiments and many other dead ends lead me to believe that there is no simple way to build the table as I would like given my current data structure.

Given this, I have two questions:
1) How would I go about building the table using my current data structure?
2) What is the standard or ideal way to structure data for this use case?

Thanks in advance.

1
11
11/9/2012 8:55:40 PM

Accepted Answer

Like you said, you could either change your data structure, or change your template code. Here is one way to keep the current structure:

{% for row_index in range(x['date']|count) %}
    <tr>
      <td>{{ x['date'][row_index]|tojson|safe }}</td>
      <td>{{ x['users'][row_index] }}</td>
    </tr>
{% endfor %}

Or you could restructure your data in python:

x = zip(x['date'], x['users'])

And then use this template:

{% for row in x %}
    <tr>
      <td>{{ row[0]|tojson|safe }}</td>
      <td>{{ row[1] }}</td>
    </tr>
{% endfor %}

You can also structure the data so that the template does not depend on the order of the cells:

from itertools import izip
x = [dict(date=d, user=u) for d, u in izip(x['date'], x['users'])]

Then you can access your data like this:

{% for row in x %}
    <tr>
      <td>{{ row['date']|tojson|safe }}</td>
      <td>{{ row['user'] }}</td>
    </tr>
{% endfor %}
25
11/9/2012 9:09:24 PM

You might use Flask-Table or for something more complex even leverage Flask-Admin.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon