(アドベントカレンダー3日目にして、ネタが尽き始めていますが、)
Flaskでフラッシュメッセージを表示する方法を説明していきます。
フラッシュメッセージは、ユーザーが何らかの行動を起こしたときに、その行動が正しく処理されたこと知らせたり、失敗したことを知らせるために利用されることが多いです。
例えば、ログイン成功時や、何らかの投稿に失敗した時などなど。
Flaskの公式ドキュメントを見れば、ざっくり書いてありますが、アレンジを加えつつ、実装していきます。
目次
- Flaskのヘルパーメソッドのflash()の説明
- Flaskのヘルパーメソッドのget_flashed_messages()の説明
- サンプルアプリを実装
- おまけ
対象
- Flaskでフラッシュメッセージを表示したい人
- Flaskでアプリケーションを作っている人
- pythonでwebサービスを作ろうとしている人
Flaskのヘルパーメソッドのflash()の説明
Flaskでフラッシュメッセージを表示する際に用いられるメソッドです。
flask/helpers.py
の中を覗いてflash()
を観察してみましょう。
def flash(message, category='message'):
flashes = session.get('_flashes', [])
flashes.append((category, message))
session['_flashes'] = flashes
message_flashed.send(current_app._get_current_object(),
message=message, category=category)
それほど複雑なことはやっていなさそうですね。
まず、第二引数でmessage以外も渡せるようですね。(今回初めて知りました^^;)
flashesという配列に、引数で渡されたmessageとcategoryを追加しています。
Flaskのヘルパーメソッドのget_flashed_messages()の説明
ビューで使用するメソッドです。get_flashed_messages()を使用すれば、指定したflash()内の文字列が、ビューで表示することができます。
引数
引数は2つ指定することができます。with_categories
とcategory_filter
です。
with_categories
デフォルトはFalse。
with_categories=True
にすると、フラッシュメッセージにもう一つ文字列を紐付けることできます。
そのもう一つの文字列をliタグのclassに設定することが多いようです。
flash("フラッシュメッセージ", "もう一つの文字列")
<li class="もう一つの文字列">フラッシュメッセージ</li>
後ほど、サンプルアプリ内で実装します。
category_filter
今回は実装の対象から外しています。
category_filter=["error"]
のように指定すると、配列の中の文字列をcategory(※1)として持つフラッシュメッセージしか表示しないようにできます。
※1 categoryとは、上の「with_categories」でいう「もう一つの文字列」です
サンプルアプリを実装
実装してなんぼ!ってことで、簡単なサンプルアプリを作りましょう。
コントローラーの実装
from flask import Flask, flash, render_template, request
app = Flask(__name__)
app.config["SECRET_KEY"] = "sample1203"
@app.route("/", methods=["GET", "POST"])
def index():
username = ""
text = ""
if request.method == "GET":
return render_template("index.html")
if request.method == "POST":
if request.form["username"] and request.form["text"]:
username = request.form["username"]
text = request.form["text"]
flash("投稿を成功しました\(^o^)/", "success")
if request.form["username"] == "":
flash("ユーザー名を入力してください。", "failed")
if request.form["text"] == "":
flash("テキストを入力してください。", "failed")
return render_template("index.html", username=username, text=text)
if __name__ == "__main__":
app.run()
ビューを実装
(少しきれいに見せるためにcssをいじっていますが、そんなに凝らなくても表示はされますw
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>サンプル</title>
<style>
li {
margin-left: -50px;
border-bottom: 0.5px solid white;
width: 100vw;
color: white;
padding-left: 10px;
}
.success {
background-color: midnightblue;
}
.failed {
background-color: deeppink;
}
</style>
</head>
<body>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<ul class=flashes>
{% for category, message in messages %}
<li class="{{ category }}">{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<h2>フラッシュメッセージを表示できるかな</h2>
{{ username }}
{{ text }}
<form action="/" method=post>
<dl>
<dt>ユーザー名:
<dd><input type=text name=username>
<dt>テキスト:
<dd><input type=text name=text>
</dl>
<p><input type=submit value=Send>
</form>
</body>
</html>
あとは、app.pyを動かすだけ!
$ python app.py
成功した時のフラッシュメッセージ
失敗した時のフラッシュメッセージ
おまけ
最後までお付き合いいただき、ありがとうございました。
少しでもお役に立てたのであれば、嬉しいです。
Renttleというサービスを開発中です。ぜひ、使ってみて、レビューをください。