Login

Template tag: split list to n sublists

Author:
movielady
Posted:
July 16, 2008
Language:
HTML/template
Version:
Not specified
Score:
3 (after 3 ratings)

Based on this snippet, adapted to split a list into n number of sublists, e.g. split a list of results into three evenly-divided sublists to enable display of the results in three columns on one page with CSS.

Tag: {% list_to_columns your_list as new_list number_of_columns %}

The split_seq solution comes from a comment by Sebastian Hempel on this post.

More info here.

 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
from django.template import Library, Node
     
register = Library()

class SplitListNode(Node):
    def __init__(self, list, cols, new_list):
        self.list, self.cols, self.new_list = list, cols, new_list

    def split_seq(self, list, cols=2):
        start = 0 
        for i in xrange(cols): 
            stop = start + len(list[i::cols]) 
            yield list[start:stop] 
            start = stop

    def render(self, context):
        context[self.new_list] = self.split_seq(context[self.list], int(self.cols))
        return ''

def list_to_columns(parser, token):
    """Parse template tag: {% list_to_columns list as new_list 2 %}"""
    bits = token.contents.split()
    if len(bits) != 5:
        raise TemplateSyntaxError, "list_to_columns list as new_list 2"
    if bits[2] != 'as':
        raise TemplateSyntaxError, "second argument to the list_to_columns tag must be 'as'"
    return SplitListNode(bits[1], bits[4], bits[3])
    
list_to_columns = register.tag(list_to_columns)

More like this

  1. Bootstrap Accordian by Netplay4 5 years, 11 months ago
  2. Bootstrap theme for django-endless-pagination? by se210 8 years, 11 months ago
  3. Bootstrap theme for django-endless-pagination? by se210 8 years, 11 months ago
  4. Reusable form template with generic view by roldandvg 9 years ago
  5. Pagination Django with Boostrap by guilegarcia 9 years, 2 months ago

Comments

movielady (on July 16, 2008):

Example usage:

{% load list_to_columns %}
{% list_to_columns people as list 3 %}
    {% for l in list %}
        (cycle through your div and ul code)
            {%for p in l %}
                (cycle through your list items)
            {% endfor %}
        (end ul and div tags)
    {% endfor %}

#

kjellmf (on September 30, 2008):

This snippet is really useful. Thanks for sharing.

One word of warning. If you pass a queryset to list_to_columns, a large number of SQL queries will be executed. To reduce the number of queries to one you could force the evaluation of the queryset prior to splitting the list:

def split_seq(self, list, cols=2):
    start = 0
    tmplist=tuple(list)  
    for i in xrange(cols): 
        stop = start + len(tmplist[i::cols]) 
        yield list[start:stop] 
        start = stop

Not sure if this is the best approach, but it reduces the number of queries.

#

gregb (on August 26, 2009):

Also, try using

from django.template import Library, Node, Variable
...
    def render(self, context):
        list = Variable(self.list).resolve(context)
        context[self.new_list] = self.split_seq(list, int(self.cols))
        return ''

in order to utilise django's variable parsing ability. (Your solution fails if you're trying to split a sub-variable, for eg

{% list_to_columns page.object_list as columns 2 %}

#

Please login first before commenting.