Pedro Assunção

Django template filter: Show list of objects as table with fixed number of columns

I recently ran into the following problem: I needed to be able to display a list of users in a table that had a maximum of X columns. Since I could not find the solution on the Internet I decided to give it a try and here is my resulting template filter to do it:

def tablecols(data, cols):
    rows = []
    row = []
    index = 0
    for user in data:
        row.append(user)
        index = index + 1
        if index % cols == 0:
            rows.append(row)
            row = []
    # Still stuff missing?
    if len(row) > 0:
        rows.append(row)
    return rows
register.filter_function(tablecols)

Then you can use it in your templates like so:

<table>
{% for row in members|tablecols:5 %}
    <tr>
    {% for member in row %}
        <td>
            {% show_simple_profile member user %}
        </td>
    {% endfor %}
    </tr>
{% endfor %}
</table>

It will break down the “members” list into a list of lists, each of the first being a group of (in this case) 5 users max.

Have fun :)

Related:

  1. [Django] Dynamic redirection after login Here’s how to redirect to the login page in django,...
  2. Django: Reverse HTTP redirect with parameters Here’s how to, from a view, redirect to another URL...


Categorised as: code snipplets, computers, software development, tips


16 Comments

  1. Serge says:

    As far as I understand the code, the table generated will render the list from left to right first and then from top to bottom. Often you need the opposite, especially if you have sorted data – say, list of countries. Basically, you will want just one row in a table where the first column has the first chunk of the list and so on.

  2. Daniel says:

    Nearly a year later, and I've found this very useful, thank you :-)

  3. ypocat says:

    rows = [ data[v:v+cols] for v in range(0,len(data),cols) ]

    fixed! :-)

    • nocivus says:

      Thanks for the one liner. My main point was to express the creation of a template filter, but your solution for the filter implementation code is by far simpler :)

      • ypocat says:

        i know, i just like to be a smartass, and i know you know that:)
        but python really allows to write basic data manipulation in 1/10th of the space of Java-like languages, and due to the smaller space taken, the code is then also better readable and manageable, at least in my view.
        the huge downside is that the compiler doesn't tell you much about broken code – you simply have to run all the branches to make sure.. which on the other hand is good because it forces you to test your code properly…
        anyway.. i've switched from Google App Engine Java to Python some time ago, and never looked back since – but this may also be because of the GAE limitations – the stuff you can do there is usually quite simple, and Python is OK for that.

  4. Christian says:

    Perhaps by now there is a better way to do this, but I found it useful. Thanks.

    I want my tables to have the same number of columns on every row…

    # Still stuff missing?
    # see how many are missing and add empty elements to complete the row
    if len(row) > 0:
    remaining = len(row)
    to_add = cols – remaining
    for c in range(to_add):
    row.append([])

    rows.append(row)

    return rows

  5. EJ says:

    Fantastic, thank you

  6. joshua says:

    Yay! Just what I needed. Thanks.

  7. Scot Hacker says:

    Oh – except for the last line, which should be:

    register.filter('tablecols', tablecols)

    • nocivus says:

      Actually it works on my environment without the name. I think Django reverts to the function name if you don't provide one ;)

  8. Scot Hacker says:

    Thanks much, works perfectly. And this is WAY cleaner and shorter than the example shown in the Django Wiki : http://code.djangoproject.com/wiki/ColumnizeTag

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>