2013-07-29 43 views
6
{% set disabled = '' %} 
{% for voter in record.voters %} 
    {% if user == voter %} 
     {% set disabled = 'disabled' %} 
    {% endif %} 
    {{ disabled }} # outputs: 'disabled' 
{% endfor %} 
{{ disabled }} # outputs: '' 

Tôi có mẫu đó trong Jinja2. Điều tôi cần là biến 'đã tắt' để hiển thị bên ngoài vòng lặp 'for'. Có thể không?Jinja2: biến cục bộ/toàn cầu

Trả lời

10

Cách đơn giản nhất để xử lý này là để di chuyển logic đặt biến số disabled cho hàm xem của bạn và gửi nó xuống mẫu sẵn sàng để sử dụng. Việc trộn logic ứng dụng với bản trình bày không phải là một ý tưởng hay, các mẫu sẽ nhận dữ liệu được phân tích càng tốt.

Điều đó nói rằng, có một hack xấu xí làm cho những gì bạn muốn có thể, được hiển thị trong câu trả lời được chấp nhận cho this question.

Giải pháp bao gồm việc bật tiện ích mở rộng do cho Jinja2 và sử dụng nó để sửa đổi mảng toàn cầu. Để kích hoạt sử dụng phần mở rộng:

app.jinja_env.add_extension('jinja2.ext.do') 

Dưới đây là giải pháp phù hợp với ví dụ của bạn:

{% set disabled = [] %} 
{% for voter in record.voters %} 
    {% if user == voter %} 
     {% do disabled.append(1) %} 
    {% endif %} 
{% endfor %} 
{% if disabled %} 
    disabled 
{% endif %} 
+0

thx . Tôi đã sửa đổi mã của tôi và đã làm như bạn đề nghị lúc đầu. –

0

By khối mặc định không thể truy cập các biến từ phạm vi bên ngoài, bạn có thể ghi đè lên điều này bằng cách sử dụng modifier scoped như vậy:

{% for item in list scoped %} 
{% endfor %} 

Xem: http://jinja.pocoo.org/docs/templates/#block-nesting-and-scope

+1

Điều đó không làm được! 'Scoped' hoạt động cho các khối không cho vòng lặp –

+0

@ c00p3r.web trong trường hợp đó tôi đề nghị mở một vấn đề cho jinja2 vì điều đó có vẻ giống như chức năng mong muốn: https://github.com/mitsuhiko/jinja2/issues –

6

Bạn có thể sử dụng một mảng/dict như Miguel gợi ý, nhưng bạn không cần phần mở rộng làm cho mỗi gia nhập ; bạn có thể thiết lập một var giả. Tôi sử dụng những điều sau đây:

{% set glob={} %} 

ở phía trên, và sau đó trong mã của tôi:

{% set _ = glob.update({'disabled':True}) %} 

Các _ biến chỉ là một hình nộm, bạn không sử dụng nó sau đó.

0

Tôi nhận thấy tôi đang trả lời một chuỗi cũ. Tuy nhiên, tôi bắt đầu sử dụng Jinja gần đây và chạy vào một vấn đề tương tự: tôi cần đếm số lượng hàng được in trong chu kỳ lồng nhau. Giải pháp của tôi là gói một biến truy cập trong một lớp và truyền một thể hiện cho khuôn mẫu. Tương tự như vậy, bạn có thể sử dụng một lớp wrapper, như vậy

class VoterStatus(object): 
    def __init__(self, status='active'): 
     self._status = status 

    def set_disabled(self): 
     self._status = 'disabled' 

    def __str__(self): 
     return self._status 

Sửa đổi mẫu của bạn cho phù

{% for voter in record.voters %} 
    {% if user == voter %} 
     {% status.set_disabled() %} 
    {% endif %} 
    {{ status }} # outputs: 'disabled' 
{% endfor %} 

Vượt qua một trường lớp Status để mẫu cho rendering:

tmplt.render(status=VoterStatus(), ...) 

... và Bob là chú của bạn.