对于块赋值内的循环?
For loop inside block assignment?
这是一个基本循环,在赋值块之外时可以正常编译:
{% for item in items %}
<p>{{item}}</p>
{% endfor %}
但是当我将循环放在 assignment block 中时,就像这样
{% set stuff %}
{% for item in items %}
<p>{{item}}</p>
{% endfor %}
{% endset %}
我得到 AssertionError: Tried to resolve a name to a reference that was unknown to the frame ('item')
。
提问的动机是我正在使用宏来避免代码重复。例如,我有许多具有不同字段的 div。 div 之一包含给用户的消息。在一个(但只有一个)案例中,我想在这个 div 中包含一个 <ul>
,所以我想遍历列表中的元素,将每个元素包装在 [=14] 中=] 标签,然后将结果 html 作为参数传递给宏。因此我的问题。
是否可以在赋值块内使用 for 循环?或者是否有更好的方法来实现同样的目标?
基于 AssertionError: Tried to resolve a name to a reference that was unknown to the frame 此问题仅存在于 Jinja2
版本 3.x
中。旧版本 2.x
工作正常。
此时在块中使用它之前需要设置变量。也许稍后他们会修复它。
{% set item = None %}
{% set stuff %}
{% for item in items %}
<p>{{item}}</p>
{% endfor %}
{% endset %}
{{ stuff }}
但是 set
对我来说有一个很大的缺点:它不能获取参数并且它只适用于 items
。
如果我设置 {% set items = other_items %}
它就不起作用
我宁愿将代码放在 macro
中以使用 stuff(main_items)
、stuff(other_items)
等
{% macro stuff(items) %}
{% for item in items %}
<p>{{item}}</p>
{% endfor %}
{% endmacro %}
{{ stuff(main_items) }}
{{ stuff(other_items) }}
最小工作代码:
from flask import Flask, render_template_string
app = Flask(__name__)
@app.route('/')
def index():
return render_template_string('''
<h1>SET</h1>
{% set item = None %}
{% set stuff_set %}
{% for item in items %}
<p>{{item}}</p>
{% endfor %}
{% endset %}
{{ stuff_set }}
<h1>MACRO</h1>
{% macro stuff_macro(items) %}
{% for item in items %}
<p>{{item}}</p>
{% endfor %}
{% endmacro %}
{{ stuff_macro(main_items) }}
{{ stuff_macro(other_items) }}
''', items=['A', 'B', 'C'], main_items=[1,2,3], other_items=[4,5,6])
if __name__ == '__main__':
#app.debug = True
app.run()
这是一个基本循环,在赋值块之外时可以正常编译:
{% for item in items %}
<p>{{item}}</p>
{% endfor %}
但是当我将循环放在 assignment block 中时,就像这样
{% set stuff %}
{% for item in items %}
<p>{{item}}</p>
{% endfor %}
{% endset %}
我得到 AssertionError: Tried to resolve a name to a reference that was unknown to the frame ('item')
。
提问的动机是我正在使用宏来避免代码重复。例如,我有许多具有不同字段的 div。 div 之一包含给用户的消息。在一个(但只有一个)案例中,我想在这个 div 中包含一个 <ul>
,所以我想遍历列表中的元素,将每个元素包装在 [=14] 中=] 标签,然后将结果 html 作为参数传递给宏。因此我的问题。
是否可以在赋值块内使用 for 循环?或者是否有更好的方法来实现同样的目标?
基于 AssertionError: Tried to resolve a name to a reference that was unknown to the frame 此问题仅存在于 Jinja2
版本 3.x
中。旧版本 2.x
工作正常。
此时在块中使用它之前需要设置变量。也许稍后他们会修复它。
{% set item = None %}
{% set stuff %}
{% for item in items %}
<p>{{item}}</p>
{% endfor %}
{% endset %}
{{ stuff }}
但是 set
对我来说有一个很大的缺点:它不能获取参数并且它只适用于 items
。
如果我设置 {% set items = other_items %}
我宁愿将代码放在 macro
中以使用 stuff(main_items)
、stuff(other_items)
等
{% macro stuff(items) %}
{% for item in items %}
<p>{{item}}</p>
{% endfor %}
{% endmacro %}
{{ stuff(main_items) }}
{{ stuff(other_items) }}
最小工作代码:
from flask import Flask, render_template_string
app = Flask(__name__)
@app.route('/')
def index():
return render_template_string('''
<h1>SET</h1>
{% set item = None %}
{% set stuff_set %}
{% for item in items %}
<p>{{item}}</p>
{% endfor %}
{% endset %}
{{ stuff_set }}
<h1>MACRO</h1>
{% macro stuff_macro(items) %}
{% for item in items %}
<p>{{item}}</p>
{% endfor %}
{% endmacro %}
{{ stuff_macro(main_items) }}
{{ stuff_macro(other_items) }}
''', items=['A', 'B', 'C'], main_items=[1,2,3], other_items=[4,5,6])
if __name__ == '__main__':
#app.debug = True
app.run()