[Django]-How to use enumerate(zip(seq1,seq2)) in jinja2?

2👍

I think the Jinja template engine has problems parsing the i, (a, b) part in the for loop here, so perhaps it is worth submitting a ticket for this. Perhaps it is intended behavior.

Anyway, you can zip with a 3-tuple here. As first iterable to zip, we can take itertools.count [python-doc]. You thus pass a reference 'count' with the itertools.count() to the context, and then you render with:

{% for i, a, b in zip(indices(), seq1, seq2) %}
     {# ... #}
{% endfor %}

For example:

>>> from jinja2 import Template
>>> from itertools import count
>>> Template('{% for i, a, b in zip(indices(), seq1, seq2) %} {{ (i, a, b) }}{% endfor %}').render(indices=count, seq1='foobar', seq2='babbaa', zip=zip)
" (0, 'f', 'b') (1, 'o', 'a') (2, 'o', 'b') (3, 'b', 'b') (4, 'a', 'a') (5, 'r', 'a')"

That being said, I strongly advise not to write business logic in the templates. In fact this is the main reason why Django template engines do not allow such syntax in the first place. It is probably much better to create the zip object in the view, and pass it through the context to the render engine.

3👍

Django doesn’t allow arbitrary code in for loop templates; you can’t even loop over a simple range defined in the template. It’s basically telling you you’re only allowed to do simple for loops, reading one item per loop from a simple input iterable.

The solution is to make your “thing to iterate over” in the code that renders the template, and pass it in as part of the context, then iterate that.

2👍

This code may help, try the code looks linke below, it works fine for me

(modified from some working code I’ve used)

when using ‘for loop’ in Jinja2, use loop.xxx to access some special vars

such as:
  loop.index        # index (1 inexed)
  loop.index0       # index (0 inexed)
  loop.revindex     # reversed ...
  loop.revindex0    # reversed ...
  loop.first        # True if first iteration
  loop.last         # True if last iteration
  loop.length
  loop.depth        # Recursive loop depth
  loop.depth0       # Recursive loop depth (0 inexed)

Code:

{% for (item_a, item_b) in zip(seq1, seq2) %}
{# important note: you may need to export __builtin__.zip to Jinja2 template engine first! I'm using htmlPy for my app GUI, I'm not sure it will or not affect the Jinja2 Enviroment, so you may need this #}
  <tr>
    <td>No.{{ loop.index0 }}</td>{# index (0 inexed) #}
    <td>No.{{ loop.index }}</td>{# index (1 started) #}
    <td>{{item_a}}</td>
    <td>{{item_b}}</td>
  </tr>
{% endfor %}

My Environment:

python 2.7.11 (I have py35 py36 but the code wasn't tested with them)

>py -2
Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:53:40) [MSC v.1500 64 bit (AMD64)] on win32
>pip2 show jinja2
Name: Jinja2
Version: 2.8

Leave a comment