Login

Group sequence into rows and columns for a TABLE

Author:
davidwtbuxton
Posted:
February 17, 2011
Language:
Python
Version:
1.2
Score:
1 (after 1 ratings)

Two template tag filters that can be used to create a table from a sequence.

<table>
{% for row in object_list|groupby_columns:3 %}
<tr>
    {% for obj in row %}
    <td>{{ obj }}</td>
    {% endfor %}
</tr>
{% endfor %}
</table>

The example above would create a table where items read from top to bottom, left to right, in 3 columns. "Empty" cells are added to the sequence by the filter so that your rows balance.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
from django import template


register = template.Library()


class ArgumentError(ValueError):
    """Missing or incompatible argument."""
    

def _regroup_table(seq, rows=None, columns=None):
    if not (rows or columns):
        raise ArgumentError("Missing one of rows or columns")

    if columns:
        rows = (len(seq) // columns) + 1
    table = [seq[i::rows] for i in range(rows)]
    
    # Pad out short rows
    n = len(table[0])
    return [row + [None for x in range(n - len(row))] for row in table]


@register.filter
def groupby_rows(seq, n):
    """Returns a list of n lists. Each sub-list is the same length.
    
    Short lists are padded with None. This is useful for creating HTML tables
    from a sequence.
    
    >>> groupby_rows(range(1, 11), 3)
    [[1, 4, 7, 10], [2, 5, 8, None], [3, 6, 9, None]]
    """
    return _regroup_table(seq, rows=int(n))


@register.filter
def groupby_columns(seq, n):
    """Returns a list of lists where each sub-list has n items.
    
    Short lists are padded with None. This is useful for creating HTML tables
    from a sequence.
    
    >>> groupby_columns(range(1, 11), 3)
    [[1, 5, 9], [2, 6, 10], [3, 7, None], [4, 8, None]]
    """
    return _regroup_table(seq, columns=int(n))

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 months ago

Comments

ptone (on February 17, 2011):

this function come from djangopackages:

def grouper(n, iterable, padvalue=None):
    "grouper(3, 'abcdefg', 'x') --> ('a','b','c'), ('d','e','f'), ('g','x','x')"
    return izip(*[chain(iterable, repeat(padvalue, n-1))]*n)

#

davidwtbuxton (on February 17, 2011):

@ptone that works to divide the sequence into n groups, but this snippet takes every nth item and puts them into groups such that the order runs down the first element then the second element then the nth element of each group. Handy for making tables where it makes sense to read items first from top-to-bottom, then left-to-right.

#

Please login first before commenting.