【Flask入門実践】Flaskのルーティングとレンダリングテンプレートを理解しよう【Python】

今回はWebアプリケーションの基礎である、Flaskでのルーティングについて解説していきます。

ルーティングとは、一言で言えば「クライアントのリクエストに対して、どのような処理を行うか」を設定することだと理解していただければ大丈夫です。

例えば、前回の記事の最後に出てきた「@app.route(‘/’)」とは「htt@://{domain}/」にアクセスした際にどのメソッドを呼び出すかを設定しているものでしたよね。今回はこちらについて少し掘り下げて解説していきます。

前回の記事を見ていない方はこちらをご確認ください。

【Flask入門実践】インストールから簡単なWebアプリケーション作成までを解説【Python】

URLに対して処理を紐づける方法

URLに対して処理を紐づける方法は簡単です。前回記事で紹介したように、「@app.route(‘/’)」といったようにroute()関数の中にURL文字列を指定するだけでできます。

例えば前回のhello.pyを少し書き変えてみましょう。

# hello.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
    return 'Index page...'

@app.route('/hello')
def hello():
    return 'Hello page...'

if __name__ == '__main__':
    app.run()

上記のように記述すると、「/」のようにルートディレクトリにアクセスすると、インデックスページ(Index page…)が表示され、「/hello」にアクセスすると「Hello page…」と表示されるようになったと思います。

このようにroute()関数を用いて、任意のURLに対し、メソッドを紐づけることができるようになります。

変数ルールの指定

セクションでマークすることにより、URLに可変セクションを追加することができます。例えばroute関数の中に「/user/<username>」と指定すると、関数で「username」を受け取ることができます。

実際に書いてみて動かしてみましょう。

# user.py
from flask import Flask
from markupsafe import escape
app = Flask(__name__)

@app.route('/user/<username>')
def show_user_name(username):
    return 'User name: %s' % escape(username)

if __name__ == '__main__':
    app.run()
解説
  • 6行目でセクション(<username>)を指定します。これによって「/user/tarutaru」というURLにアクセスすると「tarutaru」という文字列が「username」に格納されます。(7行目)
  • markupsafeのescapeはクライアントから受け取った内容をエスケープしてくれます。インジェクション対策のためエスケープは忘れないようにしましょう。

実際に「/user/{任意の文字列}」にアクセスしてURLに入力した文字列が表示されているか確認してみてください。

コンバーターオプション

コンバーターオプションを指定することで、文字列で受け取るだけでなく、整数や浮動小数などで受け取ることができるようになります。コンバーターオプションは「/user/<converter_option:valiable_name>」という形で指定するだけでOKです。

コンバーターオプションの一覧はこちらになります。

オプション 説明
string 何も指定しない場合のデフォルト値で、任意の文字列を受け取ることができます。
int 正の整数ちを受け取ることができます。
float 正の浮動小数点値を受け取ることができます。
path スラッシュを含んだ
uuid UUID文字列を受け入れることができます。

HTTPメソッドの受け取り(GET・POST)

次にHTTPメソッドとして、GETとPOSTを受け取れるようにしてみましょう。GETとPOSTを受け取るにはroute()関数にmethods引数を追加します。

# login.py
from flask import Flask
from flask import request
app = Flask(__name__)

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        return do_login()
    else:
        return show_login_form()

def do_login():
    return 'ログインします'

def show_login_form():
    return 'ログインフォームを表示'

if __name__ == '__main__':
    app.run()
解説
  • 6行目でGET・POSTメソッドを許可。これを指定しないでPOSTなどをするとエラーとなるので注意。
  • 8行目以降でPOSTでリクエストが来た場合はログイン処理を、それ以外であればログインフォームを表示するような処理を記載しています。(実際には文字列を返しているだけ)

レンダリングテンプレート

各メソッドの返す文字列にHTMLを記載することで、HTMLを組み立てることもできますが、Flaskではjulia2のテンプレートエンジンを使うことができます。これにより、ロジック部分と表示部分の分離をすることができます。

先ほどのログイン処理にテンプレートを導入して簡易的なログイン画面を作ってみましょう。

フォルダ構成は下記のようにしてみましょう。

├── login.py
└── templates
    └── login.html

ログイン処理の実装

まずは先ほど作成したログイン処理を下記のように修正してみましょう。

from flask import Flask
from flask import request
from flask import render_template
app = Flask(__name__)

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        return do_login()
    else:
        return render_template('login.html')

def do_login():
    user_name = request.form['user_name']
    password = request.form['password']
    if user_name != 'tarutaru' or password != 'blog':
        return render_template('login.html', error_message='ユーザー名かパスワードが間違っています')
    return render_template('login.html', success_message='ログイン処理成功!')

if __name__ == '__main__':
    app.run()
解説
  • 11行目のrender_templateメソッドを使うことでHTMLテンプレートを呼び出すことができます。(HTMLの内容は後述)
  • 14・15行目でPOSTメソッドで送られてきたユーザ名とパスワードを取得します。
  • 16行目以降でユーザー名とパスワードのチェックを行い、render_templateの引数にエラーメッセージ・ログイン成功のメッセージを指定してテンプレートに変数を渡しています。

テンプレートファイルの作成

次にログイン画面のテンプレートファイルを作成してみましょう。今回はtemlatesフォルダの下にlogin.htmlというファイルを作成します。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>ログイン</title>
</head>
<body>
    <form action="/login" method="post">
        <label>ユーザー名</label>
        <input type="text" name="user_name">
        <label>パスワード</label>
        <input type="password" name="password">
        <input type="submit">
    </form>
    {% if error_message %}
        <p style="color: red;">{{ error_message }}</p>
    {% endif %}
    {% if success_message %}
        <p style="color: blue;">{{ success_message }}</p>
    {% endif %}
</body>
</html>
解説
  • 15~17行目で「error_message」という変数がテンプレートに渡っていれば、エラーメッセージを表示
  • 18~20行目で「success_message」という変数がテンプレートに渡っていればログイン成功メッセージを表示

ここまで実装してから再度アプリケーションを実行すると下記のようなログイン画面が表示されると思います。

ユーザー名とパスワードがあっていれば青文字でログイン成功のメッセージが、間違っていればエラーメッセージが表示されるはずです。

まとめ

今回はFlaskでのルーティングの設定方法と、テンプレートのレンダリングの方法を解説しました。このあたりが理解できれば早速ある程度動きのあるアプリケーションの開発が始められると思います。復習がてら自分でロジックを考えて色々実装してみてください。

次はクッキーとリダイレクトについて解説していきます。

【Flask入門実践】リダイレクトとクッキーについて理解しよう【Python】