Thanks for your reply, I really like the general iterator approach.
This recipe will definitely go to my personal "standard" library.
A.
On Dec 2, 11:09 pm, Tim Chase <[EMAIL PROTECTED]> wrote:
> > If your data is in the 'data' context variable, then try this:
>
> > <table>
> > {% for d in data %}
> > {% if forloop.counter0|divisibleby:"2" %}<tr>{% endif %}
> > <td>{{d}}</td>
> > {% if forloop.counter|divisibleby:"2" %}</tr>{% endif %}
> > {% endfor %}
> > {% if data|length|divisibleby:"2" %}{% else
> > %}<td> </td></tr>{% endif %}
> > </table>
>
> > It's a little awkward, and doesn't generalize to more than two columns,
> > but it does produce properly structured HTML.
>
> It can be generalized, as I've done it in a pinch, and it looks
> something like this (untested, as I don't have my actual code
> right in front of me):
>
> <table>
> <tr>
> {% for d in data %}
> <td>{{d}}</td>
> {% if forloop.counter|divisibleby:"4" %}</tr><tr>{% endif %}
> {% endfor %}
> </tr>
> </table>
>
> HTML is forgiving if you don't have the right number of columns
> in your final row (don't know about XHTML's definition). And it
> adds a bogus row at the bottom if your dataset is divisible by N.
>
> A better way would be to make a custom template filter that
> breaks the data-set into groups.
>
> #####################################
> from itertools import izip, islice
>
> def pad(iterable, length, padding=None):
> i = 0
> for thing in iterable:
> i += 1
> yield thing
> for i in xrange(length - i):
> yield padding
>
> def columnize(dataset, args="2"):
> if "," in str(args):
> columns, padding = args.split(",",1)
> else:
> columns = args
> padding = ""
> columns = int(columns)
> row_count, leftovers = divmod(len(dataset), columns)
> if leftovers: row_count += 1
> return izip(*(
> pad(islice(dataset, i, None, columns), row_count, padding)
> for i in xrange(columns)
> ))
> #####################################
>
> and then register columnize your filter. It should presume 2
> columns, but be extensible to more than two columns with an
> optional parameter. It also takes optional padding as a
> parameter, so it can be called like
>
> <table>
> {% for thing in data|columnize:"3, " %}
> <tr>
> {% for value in thing %}
> <td>{{ value }}</td>
> {% endfor %}
> </tr>
> {% endfor %}
> </table>
>
> or
>
> <table>
> {% for thing in my_queryset|columnize %}
> <tr>
> {% for value in thing %}
> <td>
> {% if value %}
> <b>{{ value.name }}:</b>
> {{ value.other_field }}
> {% else %}
>
> {% endif %}
> </td>
> {% endfor %}
> </tr>
> {% endfor %}
> </table>
>
> which is about as clean a solution as it gets, as it guarantees
> "square" result-sets that have been padded out.
>
> -tim
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---