目次
前提条件
┣ 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>
変数のアサイン
Jinja2では、{% set %}
ブロックを使用することで、クライアントサイドで変数を定義したり、サーバーサイドから受け取った変数を再定義することが出来ます。
{% set 変数 = 値 %}
# 中略
@app.route('/')
def index():
val1 = 'abcdefg'
return render_template('index.html', val1=val1)
<!-- 中略 -->
<body>
<h1>変数のアサイン</h1>
<!-- 1.サーバーサイドから受け取った変数を表示 -->
<p>val1:{{ val1 }}</p>
<!-- 2.サーバーサイドから受け取った変数を再定義して表示 -->
{% set val1 = 'ABCDEFG' %}
<p>val1:{{ val1 }}</p>
<!-- 3.クライアントサイドで変数を定義して表示 -->
{% set val2 = 'あいうえお' %}
<p>val2:{{ val2 }}</p>
</body>
フィルター
Jinja2テンプレートで何かしらの変数を扱うとき、その変数の値を変えずに、ある処理を施して変数の値を表示したい、という場合があると思います。
そんなときはJinja2の『フィルター機能』を使用します。
{% 変数|フィルター名 %}
具体例を見てみましょう。
次の例では、変数str
に"i am ken."
という文字列をセットし、『原文→全部大文字→原文』という順番で、変数str
の値を変えずに表示させています。
<!-- 中略 -->
<body>
<h1>フィルター</h1>
{% set str = 'i am ken.' %}
<p>str:{{ str }}</p>
<p>str|upper:{{ str|upper }}</p>
<p>str:{{ str }}</p>
</body>
フィルターには大きく分けて2種類存在するので、順に紹介します。
ビルトインフィルター
Jinja2に予め用意されているフィルターのことをビルトインフィルターと呼びます。
参考 List of Builtin Filtersjinja.palletsprojects.com値(数値、文字列)に適用するビルトインフィルター
書式 | 説明 |
---|---|
値|upper |
値をすべて大文字にする |
値|lower |
値をすべて小文字にする |
値|capitalize |
値の最初の文字を大文字に、他を小文字にする |
値|abs |
絶対値を得る |
値|length |
文字数を数える(空白文字もカウント) |
値|wordcount |
単語数を数える |
値|default(初期値) |
値が未定義だった場合の初期値を設定する |
値|escape または、値|e |
値をエスケープ処理する |
値|safe |
値をエスケープ処理しない(HTMLやスクリプトがタグとしてブラウザ認識される) |
値|format |
Pythonのフォーマットを適用する |
値|trim |
先頭および末尾の空白を削除する。 |
値|urlencode |
URLエンコードする |
値|replace(検索値, 置換値) |
値を置換する(検索値に正規表現は使えません) |
1次元配列に適用するビルトインフィルター
書式 | 説明 |
---|---|
1次元配列|first |
リストの最初の値を取り出す |
1次元配列|last |
リストの最後の値を取り出す |
1次元配列|max |
リストの最大値を返す |
1次元配列|min |
リストの最小値を返す |
1次元配列|length |
リストの要素数を返す |
1次元配列|random |
リストからランダムに要素を1つ得る |
1次元配列|unique |
重複を取り除いた一意の要素のリストを得る |
1次元配列|reverse |
リストを逆順にする |
1次元配列|sort |
リストをソートする |
テンプレートフィルター
後で書きます
エスケープ
XSSなどの脆弱性対策のためにJinja2では、デフォルトでエスケープが有効化されています。
このエスケープ処理は、{% autoescape boolean %}
ブロックで有効化/無効化を切り替えることができます。
<!-- 中略 -->
<body>
{% autoescape true %}
<!-- エスケープ有効化エリア(デフォルト) -->
{% endautoescape %}
{% autoescape false %}
<!-- エスケープ無効化エリア(危険!) -->
{% endautoescape %}
</body>
では、どうして危険を犯してまでもエスケープを無効化させたいのでしょうか。
答えは、サーバーサイドから文字列として渡した値をHTMLタグやスクリプトとして、動的に処理したいときがあるからです。
変数単位でエスケープを無効化する
ビルトインフィルターのsafe
フィルターを使用します。
<!-- 中略 -->
<body>
<h1>エスケープ</h1>
{% set str = '<p>あいうえお</p>' %}
{{ str }}<!-- HTMLタグとして認識されない -->
{{ str|safe }}<!-- HTMLタグとして認識される -->
</body>
変数単位でエスケープを有効化する
ビルトインフィルターのescape
フィルターを使用します。省略してe
でも可。
<!-- 中略 -->
<body>
<h1>エスケープ</h1>
{% set str = '<p>あいうえお</p>' %}
{% autoescape false %}<!-- ここからエスケープ処理を無効化 -->
{{ str }}<!-- HTMLタグとして認識される -->
{{ str|escape }}<!-- HTMLタグとして認識されない -->
{{ str|e }}<!-- HTMLタグとして認識されない -->
{% endautoescape %}
</body>
ソースの空白行を削除する
Jinja2の{% hoge %}
ブロックを使うと、ソースコードに空白の行が残ってしまいます。動作的には問題ありませんが、良い気はしませんね。
{% set %}
ブロックを例に見てみましょう。
<!-- 中略 -->
<body>
<h1>変数のアサイン</h1>
{% set val = 'aiueo' %}
<p>val:{{ val }}</p>
</body>
この空白行は、ブロックの{%
部分に-
を付けて、{%- hoge %}
のようにすれば、削除することが出来ます。
<!-- 中略 -->
<body>
<h1>変数のアサイン</h1>
{%- set val = 'aiueo' %}
<p>val:{{ val }}</p>
</body>
このとき、%
と-
の間に空白行を空けてはいけません。
<!-- 中略 -->
<body>
<h1>変数のアサイン</h1>
{% - set val = 'aiueo' %}
<p>val:{{ val }}</p>
</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)