目次
前提条件
┣ app.py
︙
┗ templates/
┗ index.html
ターミナル(コマンドプロンプト)のカレントディレクトリは、 flaskフォルダにあるものとします。
app.py
# -*- coding: utf-8 -*-
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.run()
index.html
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Hello Jinja2</title>
</head>
<body>
<h1>Hello Jinja2</h1>
<p>Jinja2でHTMLファイルを読み込みことに成功しました。</p>
</body>
</html>
条件分岐(if)
Jinja2で条件分岐する最小のプログラムは以下のようになります。
{% if 条件式1 %}
<!-- 条件式1がtrueの場合の処理 -->
{% elif 条件式2 %}
<!-- 条件式2がtrueの場合の処理 -->
{% else %}
<!-- 条件式1、2のいずれも満たさない場合の処理 -->
{% endif %}
HTMLと組み合わせて使う
<!-- 中略 -->
<body>
<h1>Jinja2で条件分岐</h1>
{% set val = 1 %}
<p>val:{{ val|e }}</p>
<!-- valに値が入っていれば… -->
{% if val %}
{% if val==0 %}
<p>変数valには0が格納されています。</p>
{% elif val==1 %}
<p>変数valには1が格納されています。</p>
{% else %}
<p>変数valには0と1以外の値が格納されています。</p>
{% endif %}
{% endif %}
</body>
ループ(for in)
<!-- 中略 -->
<body>
<h1>forループ</h1>
{% for i in range(5) %}
<p>{{ i|e }} こんにちは</p>
{% endfor %}
</body>
1次元配列
Jinja2で1次元配列の要素を順番に取り出す最小のプログラムは以下のようになります。
{% for i in 1次元配列 %}
<!-- ループの中身 -->
{% endfor %}
HTMLと組み合わせて使う場合
<!-- 中略 -->
<body>
<h1>1次元配列のループ</h1>
{% set array = ['a', 'b', 'c', 'd', 'e'] %}
<p>配列:{{ array|e }}</p>
<ul>
{% for i in array %}
<li>{{ i|e }}</li>
{% endfor %}
</ul>
</body>
インデックスも欲しい場合
items = ['a', 'b', 'c', 'd', 'e']
for index, item in enumerate(items):
print(index, item)
Pythonのenumerate()
みたいなことをJinja2でしたい場合は、ループ中で使用することができるloop.index
またはloop.index0
変数を使用します。
loop.index
:1
から始まるインデックスloop.index0
:0
から始まるインデックス
<!-- 中略 -->
<body>
<h1>1次元配列のループ</h1>
{% set array = ['a', 'b', 'c', 'd', 'e'] %}
<p>配列:{{ array|e }}</p>
<ul>
{% for i in array %}
<li>{{ loop.index }}, {{ i|e }}</li>
{% endfor %}
</ul>
</body>
2次元配列
Jinja2で2次元配列の要素を順番に取り出す最小のプログラムは以下のようになります。
{% for i in 2次元配列 %}
{% for j in i %}
<!-- ループの中身 -->
{% endfor %}
{% endfor %}
HTMLと組み合わせて使う場合
<!-- 中略 -->
<body>
<h1>2次元配列のループ</h1>
{% set array = [['a', 'b', 'c', 'd', 'e'], ['A', 'B', 'C', 'D', 'E']] %}
<p>配列:{{ array|e }}</p>
<ul>
{% for i in array %}
<ul>
{% for j in i %}
<li>{{ j|e }}</li>
{% endfor %}
</ul>
{% endfor %}
</ul>
</body>
インデックスも欲しい場合
1次元配列のときと同様に、loop.index
またはloop.index0
変数を使用します。
ただし、1つ目のループのインデックスは、2つ目のループのインデックスで上書きされてしまうので、別途変数にセットする必要があるので注意しましょう。
<!-- 中略 -->
<body>
<h1>2次元配列のループ</h1>
{% set array = [['a', 'b', 'c', 'd', 'e'], ['A', 'B', 'C', 'D', 'E']] %}
<p>配列:{{ array|e }}</p>
<ul>
{% for i in array %}
<p>{{ loop.index }}番目のリスト</p>
<ul>
{% set index = loop.index0 %}<!-- ここで1つ目のループのインデックスをセット -->
{% for j in i %}
<li>array[{{ index }}][{{ loop.index0 }}] : {{ j|e }}</li>
{% endfor %}
</ul>
{% endfor %}
</ul>
</body>
辞書型配列
Jinja2で辞書型配列の要素を順番に取り出す最小のプログラムは以下のようになります。
{% for key, value in 辞書型配列.items() %}
<!-- ループの中身 -->
{% endfor %}
HTMLと組み合わせて使う場合
<!-- 中略 -->
<body>
<h1>辞書型配列のループ</h1>
{% set dict = {'みかん':100, 'りんご':200, 'ぶどう':400, 'なし':300, 'メロン':800} %}
<p>配列:{{ dict|e }}</p>
<dl>
{% for key, value in dict.items() %}
<dt>{{ key|e }}</dt>
<dd>{{ value|e }}</dd>
{% endfor %}
</dl>
</body>
インデックスも欲しい場合
1次元配列、2次元配列のときと同様に、loop.index
またはloop.index0
変数を使用します。
あえて説明する箇所も無いので割愛します。
loop.*
変数を使う
最後にJinja2のループの中でのみ使用できる変数を紹介します。
オプション | 説明 |
---|---|
loop.index |
1 から始まるインデックス |
loop.index0 |
0 から始まるインデックス |
loop.revindex |
後ろから数えるインデックス(5要素ある場合、5 , 4 , 3 , 2 , 1 ) |
loop.revindex0 |
後ろから数えるインデックス(5要素ある場合、4 , 3 , 2 , 1 , 0 ) |
loop.first |
ループの1番目の要素だった場合、True を返す(それ以外はFalse ) |
loop.last |
ループの最後の要素だった場合、True を返す(それ以外はFalse ) |
loop.previtem |
ループの1つ前の要素を返す(無い場合は空白) |
loop.nextitem |
ループの1つ次の要素を返す(無い場合は空白) |
<!-- 中略 -->
<body>
<h1>loop.* 変数を使う</h1>
{% set array = ['a', 'b', 'c', 'd', 'e'] %}
<p>配列:{{ array|e }}</p>
<table>
<thead>
<tr><th>i</th><th>loop.index</th><th>loop.index0</th><th>loop.revindex</th><th>loop.revindex0</th><th>loop.first</th><th>loop.last</th><th>loop.previtem</th><th>loop.nextitem</th></tr>
</thead>
<tbody>
{% for value in array %}
<tr><td>{{ i|e }}</td><td>{{ loop.index|e }}</td><td>{{ loop.index0|e }}</td><td>{{ loop.revindex|e }}</td><td>{{ loop.revindex0|e }}</td><td>{{ loop.first|e }}</td><td>{{ loop.last|e }}</td><td>{{ loop.previtem|e }}</td><td>{{ loop.nextitem|e }}</td></tr>
{% endfor %}
</tbody>
</table>
</body>
連載目次:FlaskでWebアプリケーションを開発するためのロードマップ
入門編:10記事
入門編の10記事を順に読んでいけば、FlaskでWebアプリケーションを開発する必要最小限のことが学べます。
簡単なアプリケーションであれば、セキュリティ上の観点を考慮しなかった場合公開できるでしょう。
- Flaskを『ローカルで開発する環境構築』から『プログラムの実行まで』を一通り
FlaskでWebアプリケーションを作る『全体の流れ』を大まかに理解する- Flaskのrender_templateでHTML・CSS・JavaScriptファイルを読み込む
- サーバーサイドからクライアントサイドに変数(値・リスト・辞書型配列)を渡す
- クライアントサイドで変数を処理(アサイン、フィルター、エスケープ)する
- クライアントサイドで条件分岐(if)とループ(for in)を使って、コードを簡素化する
- クライアントサイド(form)からサーバーサイドにテキストや各種コントロール、ファイルを渡す
- テンプレート継承でHTMLファイルを役割ごとに分割する
データベースに接続するデプロイする
実践編
実践編の記事では、FlaskでWebアプリケーションを公開するために欠かせないセキュリティのことや実践的なテクニックを紹介しています。
ここまで読み込めば、あとはアイディア次第でいろんなWebアプリケーションを公開できるでしょう!
セッションCookieメソッドベース・ディスパッチベーシック認証・Digest認証ログイン機能- サーバーサイドからクライアントサイドにpandas.Series、pandas.DataFrameを渡す
- クライアントサイド(form)からPOSTされた1、2次元配列を受け取る
matplotlibを使うBootstrap4を使うフォームの非同期通信(Ajax, jQuery)