web-dev-qa-db-ja.com

Jinja2のzip(list1、list2)?

Jinja2でコード生成を行っていますが、2つのリスト(変数名と型)を一緒に繰り返し処理したいのですが、これを行う簡単な方法はありますか、それとも事前に圧縮されたリストを渡すだけで済みますか? docs またはグーグルでそのような関数を見つけることができませんでした。

35
John Salvatier

適切と思われる場合は、jinja2.Environment グローバル名前空間 自体を変更します。

import jinja2
env = jinja2.Environment()
env.globals.update(Zip=zip)
# use env to load template(s)

これは、ビュー(テンプレート)ロジックをアプリケーションロジックから分離するのに役立つ場合がありますが、その逆も可能です。 # 関心の分離

41
Garrett

Flaskを使用しているかどうかについては言及していなかったので、調査結果を追加すると思いました。

render_template()で使用するには、Flaskで使用されるJinja2環境でZip()関数を使用して「Zip」フィルターを作成します。

app = Flask(__name__)
...
app.jinja_env.filters['Zip'] = Zip

テンプレート内でこれを使用するには、次のようにします。

{% for value1, value2 in iterable1|Zip(iterable2) %}
    {{ value1 }} is paired with {{ value2 }}
{% endfor %}

文字列は反復可能なJinja2であるため、文字列にZipしようとすると、クレイジーなものが表示されることに注意してください。 Zipするものが反復可能であり、文字列ではないことを確認するには、次のようにします。

{%  if iterable1 is iterable and iterable1 is not string 
   and iterable2 is iterable and iterable2 is not string %}
    {% for value1, value2 in iterable1|Zip(iterable2) %}
        {{ value1 }} is paired with {{ value2 }}
    {% endfor %}
{% else %}
  {{ iterable1 }} is paired with {{ iterable2 }}
{% endif %}
11
TheZeke

テンプレート言語では、2つのコンテナーのZipをforループで実行できるとは思いません。 Django についても同様の質問があり、jinjaテンプレートはDjangoのものに非常に近いです。

Zip形式のコンテナーを事前にビルドして、テンプレートに渡します。

>> for i,j in Zip(range(10),range(20,30)):
...     print i,j
... 

と同等です

>>> [(i,j) for i,j in Zip(range(10),range(20,30))]
3
Senthil Kumaran