Brandon Konkle
Brandon Konkle

Principal Engineer, type system nerd, Rust enthusiast, supporter of social justice, loving husband & father, avid comic & manga reader, 日本語を勉強してる。

I’m a Software Architect with more than 15 years of experience creating high performance server and front-end applications targeting web and mobile platforms, & today I lead a team at Formidable Labs.

Share


Tags


Snippet: Django Columns Filter

I was looking around for an easy way to split lists of items into columns in a way that the number of items in each column would be less than or equal to the number of items in the first column. This prevents a final column with several more items than the others.

I came across an old post from Annie Mullin that established a templatetag to do this using a generator. I liked the idea, but felt that a templatetag was too unwieldy - a filter would be simpler and easier to use in a template. So, I turned it into one:

:::python
@register.filter
def columns(lst, cols):
    """
    Break a list into ``n`` lists, typically for use in columns.

    >>> lst = range(10)
    >>> for list in columns(lst, 3):
    ...     list
    [0, 1, 2, 3]
    [4, 5, 6]
    [7, 8, 9]
    """
    try:
        cols = int(cols)
        lst = list(lst)
    except (ValueError, TypeError):
        raise StopIteration()

    start = 0
    for i in xrange(cols):
        stop = start + len(lst[i::cols])
        yield lst[start:stop]
        start = stop

This is then used in a template like this:

:::html+django
{% for column in list|columns:"3" %}
<ul>
  {% for item in column %}
    <li>
      <a href="{{ item.get_absolute_url }}">{{ item }}</a> 
    </li>
  {% endfor %}
</ul>
{% endfor %}

I’m a Software Architect with more than 15 years of experience creating high performance server and front-end applications targeting web and mobile platforms, & today I lead a team at Formidable Labs.

View Comments