【Flask】おみくじアプリを作ろう|Chapter7-1

一つ前のチャプターでは、エラーハンドリングとデバッグについて学習しました。
今回からはいよいよ、 実際に動くアプリ を開発していきましょう。
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の入門的な学習を終えた方にとって、今回のアプリ開発はとても良いステップになります。
難しそうに感じるかもしれませんが、一つ一つ丁寧に進めていけば大丈夫です。さあ、最初のアプリを一緒に作ってみましょう。
- Flask開発を Stream Deck でボタン化しよう!
-
Flaskは非常に軽量かつシンプルなフレームワークですが、それゆえに定型作業が多く、開発は単調な作業の連続になりがちです。
それこそがFlaskのメリットであり、習得難易度が低い理由でもありますが、単調な作業は退屈で、ミスも起こりやすいでしょう。
そこで役に立つのが Stream Deck 。
このような定型手順が多い作業を “ボタン化” することで視覚化。
圧倒的に 効率的 かつ ストレスフリー な開発環境が簡単に手に入ります↓↓
あわせて読みたいFlask開発をStreamDeckでボタン化しようあわせて読みたいプログラマー向けStream Deckの選び方|初心者でも失敗しないモデル比較ガイド
おみくじアプリの概要とファイル構成
この章では、今回作成する「おみくじアプリ」の全体像と、構成されるファイルについて紹介します。
これからどのようなアプリを作るのか、そしてそれがどのようなファイルで構成されているのかを理解することで、学習をスムーズに進めることができます。

アプリの仕様と動作フロー
「おみくじアプリ」は、以下のような流れで動作する簡単なWebアプリです。
- ユーザーが自分の名前を入力する。
- ボタンを押すと、ランダムに運勢(大吉〜大凶)が選ばれる。
- 運勢に応じたコメントと一緒に、結果が画面に表示される。
シンプルですが、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の中身を詳しく見ていきましょう。

おみくじアプリを作ろう
ここから、おみくじアプリを構成する5つのファイルを一つずつ作成していきます。
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がテンプレートに送られます。
テンプレートの基本レイアウト|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.htmlやresult.htmlといった子テンプレートがこのblockの中に自分の中身(フォームや結果表示)を挿入します。
名前入力フォームの実装|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>
フォームの送信ボタンです。このボタンを押すと、入力された名前が送信され、サーバー側で処理されます。
このように、index.htmlはアプリの出発点としてユーザーとの最初のインタラクションを担っています。



結果ページへのデータ表示|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.htmlのmainタグの中に挿入されて表示されます。{{ username }}さんの運勢は…
ユーザーが入力した名前がここに表示されます。app.pyからテンプレートへ渡された変数usernameを表示しています。<h2>{{ result }}</h2>
ランダムに選ばれた運勢(大吉・吉・中吉など)を大きな文字で表示しています。<p><em>{{ comment }}</em></p>
運勢に対応するコメントを斜体で表示しています。<em>タグは「強調」の意味を持ち、読みやすさやデザインのアクセントとして活用できます。<a href="/">もう一度ひく</a>
トップページに戻って再びおみくじを引けるリンクです。href="/"によりindex.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;
}bodyfont-family: sans-serif;
サンセリフ体(ゴシック体)を指定しています。読みやすく、現代的な印象を与えます。text-align: center;
ページ全体のテキストを中央寄せにします。中央寄せはシンプルで、占いアプリのような内容と相性が良いです。background-color: #f9f9f9;
少しグレーがかった白色の背景にして、画面が真っ白にならないように工夫しています。
formmargin-top: 20px;
フォームの上部に20pxの余白を追加しています。これにより、ページのヘッダーとフォームがくっつかず、見やすくなります。
buttonpadding: 8px 16px;
ボタンの内側に余白を追加しています。これによりクリックしやすく、視認性も向上します。
まとめ
きちんと動作するアプリを作成できましたか?
まだ確認していない方は、ここで実際に動かしてみましょう。
今回の章では、これまでFlaskの基礎を学習してきた皆さんが、初めて実際にWebアプリを開発するというステップに挑戦しました。
最初のアプリ開発は、うまくいかないことやわからないことが多いかもしれません。
でも、実際に「動くものを作る」ことで得られる達成感はとても大きく、次へのモチベーションにもつながります。
ここまで作り上げたあなたは、もう「Flask初心者」ではありません。
次の章では、アプリをより効率よく構成するための「Blueprint」という設計手法を学んでいきます。
より複雑なアプリケーションへとステップアップする準備を、一緒に進めていきましょう。
- サイト改善アンケート|1分だけ、ご意見をお聞かせください
-
本サイトでは、みなさまの学習をよりサポートできるサービスを目指しております。
そのため、ご利用者のみなさまの「プログラミングを学習する理由」などをアンケート形式でお伺いしています。ご協力いただけますと幸いです。
アンケート
FAQ|Flaskおみくじアプリの作り方
- Q1. Flaskで作ったアプリが「Method Not Allowed」エラーになるのはなぜ?
-
フォームでPOSTメソッドを使っている場合、対応するルート関数で
methods=['GET', 'POST']が指定されていないとエラーになります。ルート定義を確認しましょう。
- Q2. HTMLテンプレートで{{ username }}が表示されないのはなぜ?
-
テンプレートに正しく変数が渡されていない可能性があります。
render_template()でusername=usernameのように明示的に渡しているかを確認しましょう。
- Q3. おみくじ結果が毎回同じになるのはどうして?
-
random.choice()を使っていても、サーバーを再起動しない限り結果が固定されている場合は、関数の実行タイミングに問題があります。POSTリクエスト時にのみランダム処理を行うようにコードを見直してください。






