Webアプリケーションのエラーなどを表示するflashという仕組みを学びます。
エラーをしっかり確認できるようにするのはとても大切
flaskのチュートリアル、クイックスタートの「Message Flashing」を進めていきます。
クイックスタートでは概要しか記載していませんでしたので、リンク先のサンプルプログラムを動作させて検証をしていきます。
こんな人の役に立つかも
・flaskでWebアプリ開発をしたい人
・flaskのクイックスタートチュートリアルを勉強したい人
・Webアプリケーション開発の初歩の知識を勉強したい人
Message Flashingのプログラム作成
チュートリアルのプログラムでflashの使い方等を学んでいきます。
application.py
まずはviewのプログラムです。次のプログラムを「application.py」として保存しました。
from flask import Flask, flash, redirect, render_template, request, url_for
app = Flask(__name__)
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'
@app.route('/')
def index():
return render_template('index.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != 'admin' or request.form['password'] != 'secret':
error = 'Invalid credentials'
else:
flash('ログイン成功')
return redirect(url_for('index'))
return render_template('login.html', error=error)
このアプリケーションのViewのルーティングは、次のようになっています。
・ルートにアクセスすると「index.html」の表示
・「localhost:5000/login」にアクセスすると、GETメソッドのとき(初回表示)はlogin.htmlのログインフォーム表示
・「localhost:5000/login」にアクセスすると、POSTメソッドのとき(フォームのloginボタン押してのアクセス)はユーザー名とパスワードを「admin」、「secret」だと「ログイン成功」をflushしてindexにリダイレクト、失敗時は、error変数にエラーメッセージを表示
となっています。
今回は、ログインが成功したときにflushによるメッセージが表示されるようになっています。この挙動をみることで、flashの使い方を覚えたいと思います。
テンプレートのHTML
今回のテンプレートは少し実践的な作り方をしています。
「layout.html」という共通部分のHTMLに「body」部分のみを記載した「index.html」と「login.html」を準備しています。それぞれ、layout.htmlの「block body~end block」の間に違うHTMLが埋め込まれるようになっているようです。
layout.html
body部分がないHTMLです。主にflashで設定されたメッセージを表示するHTMLとなっています。
<!doctype html>
<title>My Application</title>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
{% block body %}{% endblock %}
index.html
ルートであるindexを表示したときのbody部分です。それ以外はlayout.htmlを引き継いでいます。
{% extends "layout.html" %}
{% block body %}
<h1>Overview</h1>
<p>Do you want to <a href="{{ url_for('login') }}">log in?</a>
{% endblock %}
login.html
loginでアクセスするログインページです。error変数に何か入っている場合、エラーメッセージが表示されるようになっています。
{% extends "layout.html" %}
{% block body %}
<h1>Login</h1>
{% if error %}
<p class=error><strong>Error:</strong> {{ error }}
{% endif %}
<form method=post>
<dl>
<dt>Username:
<dd><input type=text name=username value="{{
request.form.username }}">
<dt>Password:
<dd><input type=password name=password>
</dl>
<p><input type=submit value=Login>
</form>
{% endblock %}
これらのHTMLファイルは、application.pyと同じ階層に作成した、「templates」フォルダに配置します。
今回HTMLはチュートリアルのものそのままに利用しています。
プログラムを検証
プログラムを動作させるために、Pythonの仮想環境と、デバッグ用サーバーを起動させます。FLASK_APPは「application.py」に設定して起動します。詳細手順は以下の記事でまとめておりますので、ご参照ください。
「localhost:5000」へアクセスすると、次の画面が表示されます。※あらかじめブラウザのcookie等を削除して検証を推奨いたします。
「log in?」をクリックしてログイン画面に移動しましょう。ログイン画面では、Usernameが「admin」、Passwordが「secret」でログインできるようになっていますので、そのように入力して「Login」ボタンを押します。この時に、flash()のメッセージに、「ログイン成功」が設定されます。
indexにリダイレクトされます。
get_flashed_messagesに先ほどの「ログイン成功」が存在しているので、flashで設定したメッセージが表示されることになります。もう一度、log in?を押して画面をログイン画面に切り替えてみます。
layout.htmlは共通のHTMLテンプレートなので、flashのメッセージが存在している場合、login画面にもメッセージが表示されるはずなのですが、flashのメッセージは、設定した次のリクエストに反映されるメッセージのため、その次のリクエストであるloginの時点ではもうflashのメッセージが有効ではないことが確認できました。
最後に、ログインエラーの場合も試してみます。適当にユーザー名を入力してloginボタンを押してみます。
今度のErrorはflashのメッセージを利用しておらず、単純な変数の埋め込みで表示しています。
flashの使い方まとめ
⑴「application.py」のViewのプログラムの中で、「flash()」とするとメッセージが設定されます。
⑵flash()したメッセージは、テンプレートのHTMLの中で、get_flashed_message()することで取り出すことができます。
⑶flashのメッセージは、設定した次のリクエストで表示可能です。
今回のチュートリアルアプリケーションでは、layout.htmlの共通HTMLレイアウトの中にflashメッセージを取り出すプログラムを記載していますが、その中身が存在するときだけ表示するような条件分となっていますので、実際にflashによるメッセージは、ログインが成功したときのみ表示されるようにな仕組みとなっているようです。
今後よく使うのかわからないですが、とりあえずどんなものなのかは理解できました。