Làm thế nào để tăng một biến trên vòng lặp for trong mẫu jinja?


83

Tôi muốn làm điều gì đó như:

biến p là từ test.py là danh sách ['a', 'b', 'c', 'd']

{% for i in p %}
{{variable++}}
{{variable}}

kết quả đầu ra là:
1 2 3 4

Câu trả lời:


157

Bạn có thể sử dụng loop.index:

{% for i in p %}
  {{ loop.index }}
{% endfor %}

Kiểm tra tài liệu thiết kế mẫu .

Trong các phiên bản gần đây hơn, do các quy tắc xác định phạm vi, những điều sau sẽ không hoạt động:

{% set count = 1 %}
{% for i in p %}
  {{ count }}
  {% set count = count + 1 %}
{% endfor %}

Sử dụng này câu trả lời để giải quyết các vấn đề Phạm vi
faruk13

68

Sau 2.10, để giải quyết vấn đề phạm vi, bạn có thể làm như sau:

{% set count = namespace(value=0) %}
{% for i in p %}
  {{ count.value }}
  {% set count.value = count.value + 1 %}
{% endfor %}

1
Tôi gặp lỗi: TemplateSyntaxError at / list / Thẻ khối không hợp lệ trên dòng 145: 'set', mong đợi là 'endblock'. Bạn đã quên đăng ký hoặc tải thẻ này? Bật: {% set count = namespace (value = 0)%} Bạn có biết nguyên nhân của điều này không?
Andrew

55

Như Jeroen nói rằng có những vấn đề về phạm vi: nếu bạn đặt 'số lượng' bên ngoài vòng lặp, bạn không thể sửa đổi nó bên trong vòng lặp.

Bạn có thể đánh bại hành vi này bằng cách sử dụng một đối tượng thay vì một đại lượng vô hướng cho 'số lượng':

{% set count = [1] %}

Bây giờ bạn có thể thao tác đếm bên trong một vòng chia hoặc thậm chí% bao gồm%. Đây là cách tôi tăng số lượng (vâng, rất khó nhưng tốt):

{% if count.append(count.pop() + 1) %}{% endif %} {# increment count by 1 #}

Peter Hollingsworth. Cảm ơn rất nhiều vì thông tin đó, đã giúp tôi rất nhiều.
mthecreator

6
Một giải pháp khác giúp imo gọn gàng hơn một chút là khởi tạo một danh sách trống {% set count = [] %}, thêm một mục vào danh sách trong mỗi vòng lặp {% set __ = index.append(1) %}và sử dụng độ dài để hiển thị chỉ mục index|length.
eyettea

1
Ngoài ra, bạn có thể sử dụng làm tuyên bố như thế này {% do index.append(1) %} Nhưng bạn phải thêm gia hạn được mô tả ở đây
AstraSerg

2
Sửa chữa @eyettea là giải pháp làm sạch: Một giải pháp mà là một chút bụi imo là để khởi tạo một danh sách trống {% set count = [ ] %}, thêm một mục vào danh sách trong mỗi vòng lặp {% set __ = count.append(1) %}và sử dụng độ dài để hiển thị số đếmcount|length
PYB

14

Đây là giải pháp của tôi:

Đặt tất cả các bộ đếm trong một từ điển:

{% set counter = {
    'counter1': 0,
    'counter2': 0,
    'etc': 0,
    } %}

Xác định macro để tăng chúng dễ dàng:

{% macro increment(dct, key, inc=1)%}
    {% if dct.update({key: dct[key] + inc}) %} {% endif %}
{% endmacro %}

Bây giờ, bất cứ khi nào bạn muốn tăng bộ đếm 'counter1', chỉ cần thực hiện:

{{ increment(counter, 'counter1') }}

Giải pháp thanh lịch cho một vấn đề lộn xộn. Cảm ơn bạn!
SevakPrime

Rất tốt! Tôi cần một chỉ số đếm tích lũy cuộn qua hai vòng lặp for lồng nhau. Điều này hoạt động tốt cho trường hợp sử dụng đó.
jxramos

2

Tôi cũng đã đấu tranh với hành vi này. Tôi muốn thay đổi lớp div trong jinja dựa trên bộ đếm. Tôi rất ngạc nhiên rằng cách pythonic không hoạt động. Mã sau đang gửi lại bộ đếm của tôi trên mỗi lần lặp, vì vậy tôi chỉ có lớp màu đỏ.

{% if sloupec3: %}
    {% set counter = 1 %}
    {% for row in sloupec3: %}
        {% if counter == 3 %}
            {% set counter = 1 %}        
        {% endif %} 

        {% if  counter == 1: %}
           <div class="red"> some red div </div>
        {% endif %} 

        {% if counter == 2: %}
           <div class="gray"> some gray div </div>
        {% endif %} 

        {% set counter = counter + 1 %} 

    {% endfor %}

{% endif %}

Tôi đã sử dụng loop.index như thế này và nó hoạt động:

{% if sloupec3: %}

    {% for row in sloupec3: %} 

        {% if  loop.index % 2 == 1: %}
           <div class="red"> some red div </div>
        {% endif %} 

        {% if loop.index % 2 == 0: %}
           <div class="gray"> some gray div </div>
        {% endif %}  

    {% endfor %}

{% endif %}

1

nếu ai đó muốn thêm một giá trị bên trong vòng lặp thì bạn có thể sử dụng nó, nó hoạt động 100%

{% set ftotal= {'total': 0} %} 
{%- for pe in payment_entry -%}
    {% if ftotal.update({'total': ftotal.total + 5}) %}{% endif %} 
{%- endfor -%}

{{ftotal.total}}

đầu ra = 5


0

Đã tìm kiếm cách làm việc này của Django và tìm thấy bài đăng này. Có thể ai đó khác cần giải pháp django đến đây.

{% for item in item_list %}
    {{ forloop.counter }} {# starting index 1 #}
    {{ forloop.counter0 }} {# starting index 0 #}

    {# do your stuff #}
{% endfor %}

Đọc thêm tại đây: https://docs.djangoproject.com/en/1.11/ref/templates/builtins/


2
Đó là Công cụ mẫu Django, OP đã yêu cầu jinja2
Jahid

Cảm ơn đã giúp tôi!
Zohab Ali
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.