Python | 1 日 120 分 × 7 日アプリ学習:Flaskで作る超簡単Webアプリ(中級編)

Web APP Python
スポンサーリンク

2日目のゴール

2日目のテーマは
「Flaskで“動くページ”を作るためのルーティングを一段深く理解する」 ことです。

1日目は
//hello のような「固定のURL」に対して、
決まった文字列を返すだけでした。

2日目ではここから一歩進んで、

URLの一部を「変数」にする(/user/1, /user/2 など)
URLの値をPythonの引数として受け取る
存在しないURLにアクセスされたときの挙動を知る

このあたりを、しっかり体で覚えていきます。


1日目の復習:Flaskの基本の形

最小構成をもう一度確認する

まずは、1日目の最小構成を思い出しましょう。

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "こんにちは Flask!"

if __name__ == "__main__":
    app.run(debug=True)
Python

ここで押さえておきたいのは、次の3点です。

app = Flask(__name__) でアプリ本体を作る
@app.route("URL") で「URLと関数」を結びつける
関数の return がそのままブラウザに表示される

この「URL → 関数 → 返り値」の流れは、2日目以降もずっと変わりません。


動的ルーティングの入り口:URLの一部を変数にする

/user/1 と /user/2 を同じ関数で処理する

1日目のルーティングは、すべて「固定のURL」でした。

/hello
/about

でも、実際のWebアプリでは、
ユーザーごとにページが変わるようなURLがよくあります。

/users/1
/users/2
/users/3

などです。

これを、1つ1つ別の関数で書くのは現実的ではありません。
そこで使うのが「動的ルーティング」です。

from flask import Flask

app = Flask(__name__)

@app.route("/user/<name>")
def show_user(name):
    return f"こんにちは、{name} さん!"

if __name__ == "__main__":
    app.run(debug=True)
Python

ここでのポイントを深掘りします。

/user/<name><name> の部分が「変数」になっている
/user/taro にアクセスすると、name には "taro" が入ります。
/user/hanako にアクセスすると、name には "hanako" が入ります。

関数の引数 name に、URLの <name> の値が渡される
Flaskが自動的に「URLの一部」を取り出して、関数に渡してくれます。
あなたは、普通のPythonの引数として扱えばOKです。

return f"こんにちは、{name} さん!" で、名前入りのメッセージを返している
URLによって name が変わるので、表示される内容も変わります。

ブラウザで次のURLを試してみてください。

http://127.0.0.1:5000/user/taro
http://127.0.0.1:5000/user/hanako

それぞれ、名前が変わって表示されれば成功です。


型付きの動的ルーティング:<int:id> を使う

数字だけを受け取りたいときの書き方

さきほどの <name> は、文字列として扱われます。
でも、ユーザーIDや記事IDなど、「数字だけを受け取りたい」ことも多いです。

Flaskでは、URLの変数に「型」を指定できます。

from flask import Flask

app = Flask(__name__)

@app.route("/item/<int:item_id>")
def show_item(item_id):
    return f"商品ID: {item_id} のページです。"

if __name__ == "__main__":
    app.run(debug=True)
Python

ここでの重要ポイントは、

<int:item_id> と書くと、「整数として受け取る」指定になる
/item/10 にアクセスすると、item_id は整数の 10 になります。
/item/abc にアクセスすると、「マッチしないURL」として扱われます(404)。

関数の引数 item_id は、すでに int 型になっている
自分で int(item_id) と変換する必要はありません。
そのまま数値として計算に使えます。

試しに、次のURLを開いてみてください。

http://127.0.0.1:5000/item/1
http://127.0.0.1:5000/item/100

そして、/item/abc にアクセスするとどうなるかも確認してみましょう。
404(Not Found)が返ってくるはずです。


404(ページが見つからない)を意識する

存在しないURLにアクセスされたときの挙動

Webアプリでは、「存在しないURL」にアクセスされることは普通にあります。

タイポ(打ち間違い)
古いリンク
悪意あるアクセス

Flaskでは、どのルートにもマッチしないURLにアクセスされると、
自動的に「404 Not Found」が返されます。

例えば、次のようなアプリがあるとします。

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "トップページです。"

@app.route("/hello")
def hello():
    return "こんにちは!"

if __name__ == "__main__":
    app.run(debug=True)
Python

このとき、

//hello は表示される
/abc/xyz は 404 になる

という挙動になります。

ここで大事なのは、

「ルーティングで定義していないURLは、基本的に404になる」
という感覚を持つことです。

後々、404専用のページを自作することもできますが、
2日目の時点では「Flaskが勝手に404を返してくれる」と理解しておけば十分です。


例題1:ユーザーIDでプロフィールを出し分ける

簡単な「疑似データベース」を使ってみる

動的ルーティングの練習として、
ユーザーIDごとにプロフィールを表示するミニアプリを作ってみましょう。

まずは、Pythonの辞書で「疑似データベース」を用意します。

from flask import Flask

app = Flask(__name__)

USERS = {
    1: {"name": "Taro", "age": 20},
    2: {"name": "Hanako", "age": 25},
    3: {"name": "Ken", "age": 30},
}

@app.route("/")
def index():
    return "ユーザーIDを指定して /user/1 のようにアクセスしてみてください。"

@app.route("/user/<int:user_id>")
def show_user(user_id):
    user = USERS.get(user_id)
    if user is None:
        return f"ユーザーID {user_id} は見つかりませんでした。"

    return f"ユーザーID: {user_id}, 名前: {user['name']}, 年齢: {user['age']}歳"

if __name__ == "__main__":
    app.run(debug=True)
Python

ここでの重要ポイントを整理します。

USERS は「ID → 情報」の辞書
本物のデータベースの代わりに、Pythonの辞書を使っています。
USERS[1] で1番のユーザー情報が取れます。

/user/<int:user_id> で、URLの数字を user_id として受け取る
/user/1user_id = 1
/user/2user_id = 2

USERS.get(user_id) で、存在チェックをしている
get を使うことで、存在しないIDのときに None が返ります。
None のときは「見つかりませんでした」とメッセージを返しています。

ブラウザで次を試してみてください。

/user/1
/user/2
/user/999

IDによって表示が変わる感覚を、しっかり味わってほしいです。


例題2:URLの一部を「ページ名」として使う

/page/xxx で簡易な固定ページを作る

もう一つ、動的ルーティングの練習をしてみましょう。
今度は、URLの一部を「ページ名」として扱います。

from flask import Flask

app = Flask(__name__)

PAGES = {
    "about": "このサイトは Flask の練習用サイトです。",
    "help": "困ったときは、まずはコードをよく読んでみましょう。",
    "contact": "お問い合わせは、まだダミーです。",
}

@app.route("/")
def index():
    return "about, help, contact のいずれかで /page/xxx にアクセスしてみてください。"

@app.route("/page/<name>")
def show_page(name):
    content = PAGES.get(name)
    if content is None:
        return f"ページ '{name}' は存在しません。"

    return f"<h1>{name} ページ</h1><p>{content}</p>"

if __name__ == "__main__":
    app.run(debug=True)
Python

ここでのポイントは、

<name> は文字列として受け取る
/page/aboutname = "about"
/page/helpname = "help"

PAGES 辞書で「ページ名 → 内容」を管理している
存在しないページ名のときは、エラーメッセージを返している

このパターンは、
「簡易CMS(コンテンツ管理)」のようなイメージで、
実際のWebアプリでもよく出てきます。


2日目で絶対に押さえてほしい本質

「URLの一部を“変数”として扱える」という感覚

今日いちばん大事なのは、
ルーティングをこう説明できるようになることです。

固定のURL(/hello)だけでなく、
URLの一部を <name><int:id> のように「変数」として扱える。
その変数は、対応する関数の引数として受け取れる。
受け取った値によって、返す内容を変えられる。

これができると、
「ユーザーごとのページ」「記事ごとのページ」など、
一気に“本物のWebアプリ”に近づきます。

3日目以降は、
ここに「テンプレート(HTMLファイル)」や「フォーム入力」などを足していきます。
でも、どれだけ機能が増えても、
根っこにあるのは今日やった

URL
関数
引数(URLから渡される値)
返り値(HTMLや文字列)

という流れです。

ここまで来たあなたは、
もう「Flaskでページを出せる人」ではなく、
「URL設計を意識してWebアプリを組み立て始めた人」 です。
この一歩は、かなり大きいよ。

タイトルとURLをコピーしました