Flask実践|おみくじアプリを作ってみよう【チャプター7-01】

ながみえ

一つ前のチャプターでは、エラーハンドリングとデバッグについて学習しました。

今回からはいよいよ、 実際に動くアプリ を開発していきましょう。

Chapter1:Flask入門編
Chapter2:Jinja2入門編
Chapter3:フィルター編
Chapter4:フォーム編
Chapter5:データベース編
Chapter6:エラーハンドリングとデバッグ編
Chapter7:アプリ開発編

 ・Chapter7-1:おみくじアプリを作ろう ◁今回はここ
 ・Chapter7-2:Blueprintを使おう
 ・Chapter7-3:メモ帳アプリを作ろう
 ・Chapter7-4:ToDoアプリを作ろう

これまでFlaskの基本的な使い方、テンプレートエンジンの使い方、フォームの仕組み、データベース操作など、段階的にFlaskの基礎を学んできました。

ここからはいよいよ、学んできた知識を使って実際にWebアプリケーションを作ってみましょう。

この章では、「おみくじアプリ」を題材にして、簡単なWebアプリケーションを作成します。

自分の名前を入力してボタンを押すと、ランダムに選ばれた運勢とコメントが表示されるアプリです。

このアプリを作成することで、以下のような内容を実践的に復習できます。

  • Flaskの基本的なルーティングとテンプレートの使い方
  • HTMLフォームから値を受け取って処理する方法
  • Pythonの標準ライブラリ(random)との連携
  • Jinja2テンプレートの継承や変数展開の活用
  • CSSによる簡単なデザイン調整

Flaskの入門的な学習を終えた方にとって、今回のアプリ開発はとても良いステップになります。

難しそうに感じるかもしれませんが、一つ一つ丁寧に進めていけば大丈夫です。さあ、最初のアプリを一緒に作ってみましょう。

本記事は 有料記事(100円)ですが、現在は期間限定で無料公開中です。

<<前のページ

Flaskの記事一覧

次のページ>>

おみくじアプリの概要とファイル構成

この章では、今回作成する「おみくじアプリ」の全体像と、構成されるファイルについて紹介します。

これからどのようなアプリを作るのか、そしてそれがどのようなファイルで構成されているのかを理解することで、学習をスムーズに進めることができます。

【Python】勉強猫がノートパソコンを前にして学習を始める様子。記事内の学習スタート用イラスト

アプリの仕様と動作フロー

「おみくじアプリ」は、以下のような流れで動作する簡単なWebアプリです。

  1. ユーザーが自分の名前を入力する。
  2. ボタンを押すと、ランダムに運勢(大吉〜大凶)が選ばれる。
  3. 運勢に応じたコメントと一緒に、結果が画面に表示される。

シンプルですが、FlaskでWebアプリを作る際の基本的な流れがすべて詰まっています。

使用するファイルとフォルダ構成

今回のアプリでは、以下の5つのファイルを作成・使用します。以下のように保存してください。

omikuji_app/
├── app.py                 # Flaskのメインプログラム
├── static/
│   └── style.css          # デザイン(CSS)ファイル
├── templates/
│   ├── base.html          # テンプレートの共通レイアウト
│   ├── index.html         # ユーザー入力フォームのページ
│   └── result.html        # おみくじ結果を表示するページ
  • app.py
    FlaskアプリのメインとなるPythonファイルです。ルーティングやフォーム処理、テンプレートへのデータ渡しなど、アプリ全体の制御を行います。
  • base.html
    すべてのページに共通するHTMLの骨組み(テンプレート)です。タイトルやヘッダー、CSSの読み込みなどを含みます。
  • index.html
    ユーザーの名前入力フォームを表示するページです。base.htmlを継承して作られています。
  • result.html
    入力された名前とランダムに選ばれたおみくじ結果を表示するページです。こちらもbase.htmlを継承しています。
  • style.css
    アプリ全体の見た目を整えるCSSファイルです。文字のフォントやボタンのスタイルなどを指定します。

これらのファイルが連携することで、一つのWebアプリケーションとして動作します。それでは、次の章ではアプリの中心となるapp.pyの中身を詳しく見ていきましょう。

Flaskアプリのメイン処理|app.pyの全体像と解説

まずは、Flaskアプリの中心となるPythonコードを見てみましょう。

以下は、今回作る「おみくじアプリ」の中核となるapp.pyのコードです。

from flask import Flask, render_template, request
import random

app = Flask(__name__)

# おみくじの結果とコメントの辞書を定義
OMIKUJI_COMMENTS = {
    "大吉": ["今日はすべてがうまくいく予感!", "何をやっても絶好調!"],
    "中吉": ["まずまず良い日になりそう。", "焦らず行動すれば吉。"],
    "小吉": ["ちょっとした幸せが訪れるかも。", "日常の中にチャンスあり。"],
    "吉":   ["穏やかな一日になりそう。", "笑顔を忘れずに。"],
    "末吉": ["午後に運気アップの兆し!", "小さなことからコツコツと。"],
    "凶":   ["慎重に行動を。トラブルには注意。", "体調管理に気をつけよう。"],
    "大凶": ["逆にレア運!悪い日こそ学びのチャンス。", "厄を落として運気上昇の始まり!"]
}

# ルートURLにアクセスした時の処理
@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        # フォームから名前を取得
        username = request.form.get('username')
        # おみくじの結果とコメントをランダムに選ぶ
        result = random.choice(list(OMIKUJI_COMMENTS.keys()))
        comment = random.choice(OMIKUJI_COMMENTS[result])
        # 結果をテンプレートに渡して表示
        return render_template('result.html', username=username, result=result, comment=comment)
    # 初回アクセス時は入力フォームを表示
    return render_template('index.html')

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

このファイルがアプリ全体の心臓部です。フォームの処理、ランダム選択、結果の表示までを一括で行っています。

なお、以下の解説文内のリンクは、その内容の詳細をまとめた記事へ繋がっています。復習したい方はクリックして移動してください。

  • from flask import Flask, render_template, request
    Flaskの基本機能とテンプレート表示、フォームデータ取得のためのモジュールをインポートします。
  • app = Flask(__name__)
    Flaskアプリのインスタンスを生成します。Flaskではこのようにしてアプリを作成します。
  • OMIKUJI_COMMENTS
    運勢とコメントのセットを辞書で定義しています。Pythonの辞書型 を用いています。
  • @app.route('/', methods=['GET', 'POST'])
    /(トップページ)へのアクセスに対してGETとPOSTの両方のリクエストを処理します。(フォーム処理の基本
  • request.form.get('username')
    ユーザーが入力した名前をHTMLフォームから取得します。
  • random.choice()
    Pythonの 標準ライブラリrandom を使って、おみくじの結果とコメントをランダムに選びます。
  • render_template()
    HTMLテンプレートに値を渡して表示します。username, result, commentがテンプレートに送られます。
【Python】勉強猫がノートパソコンを見ながら考え込む様子。記事内の休憩用イラスト

base.html:テンプレートの基本レイアウト

Flaskでは、複数のページに共通する部分(たとえばHTMLの<head><header>など)を一つのファイルにまとめることができます。

これを テンプレートの継承 といい、その基礎となるファイルが今回のbase.htmlです。

以下は、今回使用するbase.htmlの中身です。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>おみくじアプリ</title>
    <!-- 外部CSSファイルを読み込む -->
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
    <header>
        <h1>Flask おみくじアプリ</h1>
    </header>
    <main>
        {% block content %}{% endblock %}
    </main>
</body>
</html>
  • <!DOCTYPE html><body>
    一般的なHTML5のページ構造です。<head>タグの中で文字コードやタイトルを指定し、<body>タグの中にページの本体を記述します。
  • <link rel="stylesheet" 中略 ">
    静的ファイル(CSSや画像など)をstaticフォルダに保存します。
    詳細は CSSの学習記事 を参照ください。
  • <header><h1>Flask おみくじアプリ</h1></header>
    アプリの全ページに表示される共通の見出しです。どのページからアクセスしても一貫性のあるタイトルが表示されます。
  • {% block content %}{% endblock %}
    ここが テンプレート継承 の核となる部分です。具体的には、index.htmlresult.htmlといった子テンプレートがこのblockの中に自分の中身(フォームや結果表示)を挿入します。
テンプレート継承の役割

base.htmlを使うことで、以下のようなメリットがあります。

  • HTMLの共通部分を一か所にまとめることで、コードの重複を減らす
  • デザインの変更もbase.html一か所の修正で済み、メンテナンス性が高まる
  • アプリ全体に統一感を持たせる

このbase.htmlは、Flaskアプリの「土台」のような存在です。この土台を活かして、それぞれのページを作っていきます。

index.htmlの作成|名前入力フォームの実装

index.htmlは、おみくじアプリのスタート画面として、ユーザーが名前を入力するためのフォームを提供します。

このページはbase.htmlを継承して作られており、見た目の統一感を保ちつつ、動的な内容を追加する構成になっています。

以下がその内容です。

{% extends 'base.html' %}

{% block content %}
<form method="POST" action="/">
    <label for="username">あなたの名前:</label>
    <input type="text" name="username" id="username" required>
    <button type="submit">おみくじを引く!</button>
</form>
{% endblock %}
  • {% extends 'base.html' %}
    base.htmlを継承する宣言です。これにより、共通レイアウト(タイトルやヘッダーなど)がこのページにも反映されます。
  • {% block content %}{% endblock %}
    この部分がbase.htmlで定義されていた{% block content %}に挿入されます。つまり、mainタグの中にフォームが挿入される形になります。
  • <form method="POST" action="/">
    フォームの送信先と送信方法を指定しています。ここではPOSTメソッドを使って/(トップページ)にデータを送信します。
    • method="POST"は、フォームのデータをHTTP POSTメソッドで送信することを意味します。
    • action="/"は、送信先のURLをトップページに指定していることを示します。これはapp.py@app.route('/', methods=['GET', 'POST'])と対応しています。
  • <input type="text" name="username" id="username" required>
    ユーザー名の入力欄です。
    • name="username"は、サーバー側でこの値を受け取るときの名前になります(request.form.get('username')で取得)。
    • required属性があるため、ユーザーが空欄のまま送信することはできません。
  • <button type="submit">おみくじを引く!</button>
    フォームの送信ボタンです。このボタンを押すと、入力された名前が送信され、サーバー側で処理されます。
フォームの動作の流れ
  1. ユーザーが名前を入力し、「おみくじを引く!」ボタンを押す。
  2. フォームがPOSTリクエストとして送信される。
  3. app.pyindex()関数がPOSTリクエストを受け取り、名前を取得。
  4. ランダムなおみくじ結果とコメントを生成。
  5. result.htmlテンプレートに情報を渡して結果画面を表示。

このように、index.htmlはアプリの出発点としてユーザーとの最初のインタラクションを担っています。

あわせて読みたい
【HTML】レッスン1-06:フォーム作成の基本と実践ガイド
【HTML】レッスン1-06:フォーム作成の基本と実践ガイド
あわせて読みたい
Flask学習|フォームの基本とHTTPメソッドの使い方【チャプター4-02】
Flask学習|フォームの基本とHTTPメソッドの使い方【チャプター4-02】
【Python】勉強猫がコーヒーを片手にリラックスしている様子。記事内の休憩用イラスト

result.htmlの作成|結果ページへのデータ表示

result.htmlはユーザーがフォームに名前を入力して送信したあとに表示されるページです。

ここではサーバー側(app.py)で生成されたおみくじの結果と、それに対応するコメントを表示します。

このテンプレートもbase.htmlを継承しており、共通のレイアウトの中に結果を表示する構造になっています。

以下がその中身です。

{% extends 'base.html' %}

{% block content %}
<p>{{ username }}さんの運勢は…</p>
<h2>{{ result }}</h2>
<p><em>{{ comment }}</em></p>

<a href="/">もう一度ひく</a>
{% endblock %}
  • {% extends 'base.html' %}
    アプリ全体の共通レイアウトを継承する宣言です。これにより、HTMLの骨組みやCSSの読み込みなどが一貫して適用されます。
  • {% block content %}{% endblock %}
    結果表示に関する内容をこのブロック内に書いています。これがbase.htmlmainタグの中に挿入されて表示されます。
  • {{ username }}さんの運勢は…
    ユーザーが入力した名前がここに表示されます。app.pyからテンプレートへ渡された変数usernameを表示しています。
  • <h2>{{ result }}</h2>
    ランダムに選ばれた運勢(大吉・吉・中吉など)を大きな文字で表示しています。
  • <p><em>{{ comment }}</em></p>
    運勢に対応するコメントを斜体で表示しています。<em>タグは「強調」の意味を持ち、読みやすさやデザインのアクセントとして活用できます。
  • <a href="/">もう一度ひく</a>
    トップページに戻って再びおみくじを引けるリンクです。href="/"によりindex.htmlを再度表示します。
表示の流れまとめ
  1. app.pyでフォームを受け取り、運勢(result)とコメント(comment)をランダムに生成。
  2. render_template()result.htmlにその情報を渡す。
  3. {{ username }}{{ result }}{{ comment }}で受け取った情報をHTML内に表示。

このように、Flaskではテンプレート内で{{ }}を使うことで、Pythonから渡されたデータをHTMLに埋め込むことができます。

これがFlaskと Jinja2 の大きな特徴です。

style.cssでアプリを整える|基本スタイルの適用法

Webアプリケーションでは、機能だけでなく「見た目」も重要です。特に初心者が作るアプリでも、CSSで少し手を加えるだけで印象がぐっと良くなります。

今回の「おみくじアプリ」では、以下のような簡単なCSSファイルを用意し、背景色や文字の配置、ボタンの見た目を整えています。

以下がその内容です。

body {
    font-family: sans-serif;
    text-align: center;
    background-color: #f9f9f9;
}

form {
    margin-top: 20px;
}

button {
    padding: 8px 16px;
}
  1. body
    • font-family: sans-serif;
      サンセリフ体(ゴシック体)を指定しています。読みやすく、現代的な印象を与えます。
    • text-align: center;
      ページ全体のテキストを中央寄せにします。中央寄せはシンプルで、占いアプリのような内容と相性が良いです。
    • background-color: #f9f9f9;
      少しグレーがかった白色の背景にして、画面が真っ白にならないように工夫しています。
  2. form
    • margin-top: 20px;
      フォームの上部に20pxの余白を追加しています。これにより、ページのヘッダーとフォームがくっつかず、見やすくなります。
  3. button
    • padding: 8px 16px;
      ボタンの内側に余白を追加しています。これによりクリックしやすく、視認性も向上します。
見た目の改善効果

このようなシンプルなCSSでも、まったく装飾のないページと比べて、視覚的に非常に見やすく、親しみやすい印象を与えることができます。

今回は最小限の装飾ですが、今後はアニメーションや画像、レスポンシブデザインなどを加えることで、より魅力的なアプリに発展させることができます。

まとめ

きちんと動作するアプリを作成できましたか?

まだ確認していない方は、ここで実際に動かしてみましょう。

今回の章では、これまでFlaskの基礎を学習してきた皆さんが、初めて実際にWebアプリを開発するというステップに挑戦しました。

最初のアプリ開発は、うまくいかないことやわからないことが多いかもしれません。

でも、実際に「動くものを作る」ことで得られる達成感はとても大きく、次へのモチベーションにもつながります。

ここまで作り上げたあなたは、もう「Flask初心者」ではありません。

次の章では、アプリをより効率よく構成するための「Blueprint」という設計手法を学んでいきます。

より複雑なアプリケーションへとステップアップする準備を、一緒に進めていきましょう。

もっと分かりやすい学習サイトにするために

この記事を読んで「ここが分かりにくかった」「ここが難しかった」等の意見を募集しています。

世界一わかりやすいFlask学習サイトにするため、ぜひ 問い合わせフォーム からご意見下さい。

<<前のページ

Flaskの記事一覧

次のページ>>

FAQ|Flaskおみくじアプリの作り方

Q
Q1. Flaskで作ったアプリが「Method Not Allowed」エラーになるのはなぜ?

フォームでPOSTメソッドを使っている場合、対応するルート関数でmethods=['GET', 'POST']が指定されていないとエラーになります。ルート定義を確認しましょう。

Q
Q2. HTMLテンプレートで{{ username }}が表示されないのはなぜ?

テンプレートに正しく変数が渡されていない可能性があります。render_template()username=usernameのように明示的に渡しているかを確認しましょう。

Q
Q3. おみくじ結果が毎回同じになるのはどうして?

random.choice()を使っていても、サーバーを再起動しない限り結果が固定されている場合は、関数の実行タイミングに問題があります。POSTリクエスト時にのみランダム処理を行うようにコードを見直してください。

記事URLをコピーしました