読み込み中...

PythonとFlaskでWebアプリ開発!初心者でも簡単10ステップガイド

PythonとFlaskを使ったWebアプリ開発のガイドブック Python
この記事は約33分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

PythonとFlaskのWebアプリは、小さな画面表示からURL、テンプレート、データ保存、フォーム、認証、公開へ広げると整理しやすくなります。初心者はapp.pytemplatesstaticrouterequestの役割を混同しやすいため、Web開発の学習ガイドとして動く最小構成から接続します。

Pythonは読みやすく、Flaskは必要な部品を選ぶ設計です。自由度が高いぶん、フォルダ構成、設定、拡張ライブラリの責務を早めに分けますし、ここを基本と考えるとよいでしょう。サンプルコードには期待される表示を添え、動作未確認の結果を断定しません。

FlaskはWSGIアプリケーションフレームワークです。一次情報としてPython公式ドキュメントFlask公式ドキュメントを参照し、PythonによるWeb開発で使う構成を確認します。

動作確認環境
  • Python 3.12.13
  • Flask 3.1.x / Flask-SQLAlchemy 3.1.x / Flask-WTF 1.2.x / Flask-Login 0.6.x
  • Google Chrome 126相当のモダンブラウザ
📖 この記事で学べること
  • PythonとFlaskを使うWeb開発の全体像
  • pipvenvflask runによる起動手順
  • @app.route、ビュー関数、Jinja2テンプレートの関係
  • Flask-SQLAlchemy、Flask-WTF、Flask-Loginの使い分け
  • Gunicornを使った公開時の考え方

Pythonとは

Pythonは、読みやすい文法と豊富な標準ライブラリを持つ汎用プログラミング言語です。defで関数、classでクラス、importで外部モジュールを扱います。Web開発へ進む前に、変数、条件分岐、関数、例外処理を押さえると安定します。

FlaskアプリでもPythonの基礎はそのまま使われますし、ここがポイントです。returnでレスポンス本文を返し、ifでフォーム送信時の処理を分け、tryexceptで例外に備えます。Pythonの基礎がWeb開発に直結するため、プログラミングの学習ガイドとして無駄が少ない進め方です。

Pythonの特徴

Pythonの特徴は、ブロックを波かっこではなくインデントで表す点です。forwhilewithifの内側は字下げでまとまり、見た目と処理範囲が一致します。空白がずれるとIndentationErrorになり、初心者には原因が見えにくい場合があると理解できます。

Pythonにはlistdicttuplesetなどの組み込み型があり、JSONに近いデータ構造も自然に扱えます。Flaskでrequest.formsessionを読むときも、型の理解が土台になります。

Pythonの利点

PythonはWebアプリ、データ分析、自動化、API連携など幅広く使われますが、これは押さえたい点です。Web開発ではFlask、Django、FastAPIなどを目的に応じて選べます。選択肢が多いため、初心者は最初の教材を絞るほうが進めやすくなるのが基本です。

FlaskはPythonコードとHTTPレスポンスの関係を見やすく保てます。Flaskクラス、@app.routeデコレータ、ビュー関数を読めば入口を理解できると覚えるとよいでしょう。Web開発のサンプルコードを自分で変えながら学ぶ場合、この小ささが学習ガイドとして機能するのが目安です。

Pythonのインストール方法

Pythonを導入する場合、Python公式ダウンロードページからOSに合うインストーラを取得します。WindowsではAdd python.exe to PATHを有効にすると、pythonコマンドをターミナルから呼び出しやすくなります。

複数バージョンが入っている環境ではpythonpython3pyのどれが使えるか確認すると考えられます。python --versionでバージョンを見て、パッケージ導入には同じ環境のpipを使います。基礎はPython初心者のための完全ガイドも参考になるのがポイントです。

Flaskとは

Flaskは、PythonでWebアプリケーションを作る軽量フレームワークです。URLと関数を結び付け、関数から文字列やHTMLを返してページを作れます。プログラミングの基礎を学びながらWeb開発の流れを確認したい初心者にも扱いやすい構成です。

Flaskは認証、データベース、フォームなどを最初から大量に抱え込む設計ではありません。必要に応じてFlask-SQLAlchemyFlask-WTFFlask-Loginなどを追加すると言えるでしょう。小さく始めて機能を足す考え方を理解すると、サンプルコードの意図も読み取りやすくなります。

Flaskの特徴

Flaskの中心には、アプリケーションオブジェクト、ルーティング、リクエスト、レスポンスがあります。app = Flask(__name__)でアプリを作り、@app.route('/')でURLを関連付け、関数の戻り値がHTTPレスポンスになるのが基本です。この直線的な読み方が、PythonによるWeb開発の入口です。

自由度が高いことは設計判断も増えるという意味です。ファイル配置、設定値の分離、データベース接続の初期化は、アプリが大きくなるほど影響します。Flaskの学習ガイドでは、最初に小さな構造を決めてから拡張します。

Flaskの利点

Flaskは、画面を少しずつ増やすアプリやAPIの試作に向きますし、これが一つの目安です。Pythonファイルひとつから始められ、templatesstaticを追加すれば、HTML、CSS、JavaScriptも組み込めます。大規模な認可や管理画面が最初から必要なら、Djangoなどとの比較も必要です。

学習目的と公開目的を分けると判断しやすくなります。初心者がHTTP、URL、HTMLテンプレート、フォーム処理を理解する段階なら、Flaskの短いサンプルコードは読み解きやすい材料です。Pythonのプログラミング経験が浅くても、対応関係をひとつずつ確認できるのが目安です。

Flaskのインストール方法

Flaskの導入にはpipを使います。プロジェクトごとに依存関係を分けるため、venvで仮想環境を作ってからインストールする運用が一般的です。短い確認なら次のコマンドでFlaskを入れられます。

pip install flask

結果: 期待される出力は、Flask本体と依存パッケージがインストールされ、Successfully installedに近いメッセージが表示される状態です。

⚠️ 注意: pipが別のPython環境を参照していると、インストール後にModuleNotFoundErrorになる場合があるのがポイントです。python -m pip install flaskのように、実行するPythonとパッケージ管理を結び付ける書き方も検討します。

PythonとFlaskでの開発環境の設定

PythonとFlaskの開発環境では、エディタ、ターミナル、仮想環境、依存関係ファイルをそろえます。エディタはVisual Studio CodeやPyCharmなどが候補になり、ターミナルではpythonpipflaskを操作するのが一般的です。Web開発の前にコマンドの実行場所を確認するのが一般的です。

プロジェクト用フォルダを作り、app.pytemplatesstaticを置く準備をします。依存関係を記録する場合はrequirements.txtを使い、公開時にも同じパッケージを入れられる形にします。初心者向け学習ガイドでも、この構成を早めに覚えると混乱が減りますし、ここがポイントです。

Pythonの開発環境の設定

Pythonの開発では、仮想環境を作ってプロジェクト単位でライブラリを分けますが、覚えておくと役立つでしょう。代表的にはpython -m venv .venvで環境を作り、Windowsでは.venvScriptsactivate、macOSやLinuxではsource .venv/bin/activateを使います。学習環境によってはシェルの実行ポリシー調整が必要です。

pip freezepip listで導入済みパッケージを確認できます。Web開発では複数の拡張を入れるため、どのPython環境に何を入れたかが不明だとエラーの原因になるのが現実的です。環境整理は後のデプロイにもつながりますが、これは押さえたい点です。

Flaskの開発環境の設定

Flaskには開発用サーバーがあり、ローカルでブラウザ表示を確認できます。現在のFlaskではアプリケーションファイルを自動検出できる場合もありますが、明示するなら環境変数や--appオプションを使います。古い教材のFLASK_APPだけに依存せず、公式ドキュメントに合う書き方を選びますし、これが一つの目安です。

flask run

結果: 期待される出力は、開発サーバーが起動し、http://127.0.0.1:5000のようなURLがターミナルに表示される状態です。

このコマンドは、カレントディレクトリのapp.pywsgi.pyを探して起動すると整理できます。ファイル名が違う場合は、次のように環境変数で入口を示します。macOSやLinux系のシェルではexportを使いるのが現実的です。

export FLASK_APP=app.py

結果: 期待される出力は特にありませんが、同じターミナル内でflask runapp.pyを参照する状態になります。

Windowsのコマンドプロンプトでは、環境変数の書き方が変わりますし、ここを基本と考えるとよいでしょう。PowerShellでは別の構文になるため、使っているシェルを確認してから入力します。コマンドプロンプトなら次の形式です。

set FLASK_APP=app.py

結果: 期待される出力は特にありませんが、現在のコマンドプロンプトでFlaskアプリの入口がapp.pyとして扱われます。

サンプルコード1:開発環境の設定

最小のFlaskアプリはPythonファイルひとつで作れますし、ここがポイントです。from flask import Flaskでクラスを読み込み、app = Flask(__name__)でアプリケーションを作ります。@app.route('/')を付けた関数から文字列を返すると整理できます。

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, Flask!'

結果: 期待される表示は、ブラウザでhttp://localhost:5000へアクセスしたときにHello, Flask!という文字列が見える状態です。

これで、Pythonの関数がHTTPレスポンスになる関係を確認できると理解できます。Web開発では、この対応関係を理解してからURL、テンプレート、フォーム、データベースを接続します。サンプルコードを変更するなら、返す文字列を変えるところから始めると差分が見えると理解できます。

Flaskアプリの基本的な構造

Flaskアプリは、ファイルの置き場所とPythonコードの入口を分けると整理できると覚えるとよいでしょう。小規模ならapp.pyに処理をまとめ、HTMLはtemplates、CSSや画像はstaticに置きます。規模が大きくなるとblueprintやパッケージ構成を使いると覚えるとよいでしょう。

初心者の段階ではひとつのファイルから始めても問題ありません。要点は、どのURLがどの関数に届き、どのテンプレートを返すかです。PythonとFlaskのプログラミングでは、構造を先に見取り図として持つとエラーを追いやすくなります。

分類要素役割関連するcode注意点
入口app.py起点Flask(__name__)起動設定と合わせる
URLルートパスと関数を結ぶ@app.route重複に注意する
処理ビュー関数レスポンスを返すreturn戻り値を意識する
画面テンプレートHTMLを生成するrender_templatetemplatesへ置く
静的CSS見た目を整えるurl_for('static')キャッシュに注意する
入力フォーム入力を受けるrequest.formCSRFを考える
検証WTForms値を検査するvalidate_on_submitエラー表示を用意する
保存SQLite小規模保存sqlite:///位置を決める
ORMSQLAlchemyDBを扱うdb.Model変更履歴を考える
認証ログインユーザーを識別login_user平文保存を避ける
保護ログイン必須閲覧制限@login_required遷移先を決める
設定SECRET_KEY署名に使うapp.config公開しない
環境venv依存を分離python -m venv有効化を確認
依存requirements再現するpip freeze不要な依存を避ける
起動開発サーバーローカル確認flask run本番に使わない
公開WSGI本番接続gunicornプロキシを考える
HTTPGETページ取得methods=['GET']状態変更を避ける
HTTPPOST送信処理methods=['POST']検証を入れる
遷移redirect別URLへ移すredirect二重送信を避ける
URL生成url_forURLを作るurl_for直書きを減らす
通知flash一時通知flash表示側も必要
セッションsession状態を持つsession秘密鍵が必要
変数Jinja2値を埋め込む{{ name }}エスケープを理解
条件if表示を分ける{% if %}複雑化を避ける
反復for一覧を出す{% for %}空表示を決める
DB主キー行を識別primary_key=True重複を避ける
DB一意制約重複を防ぐunique=True例外を扱う
DBNULL制約空値を防ぐnullable=Falseフォームでも検証
安全ハッシュパスワード保護generate_password_hash平文を避ける
運用ログ原因を追うlogging個人情報に注意

Flaskアプリのフォルダ構造

小さなアプリのフォルダは、myapp/static/templates/app.pyrequirements.txtに分けると読みやすくなります。staticにはCSSや画像、templatesにはHTMLを置きます。app.pyはルーティングと初期化を持つ入口です。

Flaskアプリの基本的なコード構造

Flaskの基本コードは、読み込み、アプリ作成、ルート定義の順で並びますが、これは押さえたい点です。Pythonの関数定義にデコレータを付けるだけなので、Web開発の最小単位が見えます。次のサンプルコードは、ルートURLで文字列を返すると考えられます。

# 1. Flaskライブラリのインポート
from flask import Flask

# 2. Flaskインスタンスの作成
app = Flask(__name__)

# 3. ルート('/')へのアクセスを定義
@app.route('/')
def hello_world():
    return 'Hello, Flask!'

結果: 期待される表示は、ルートURLにアクセスしたときにHello, Flask!が本文として返る状態です。

サンプルコード2:基本的なFlaskアプリの作成

具体的なファイル名を付けるなら、次の内容をapp.pyとして保存します。関数名はhomeですが、URLの表示内容は戻り値で決まります。関数名とページ内容を混同しないようにすると言えるでしょう。

# app.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
    return 'Welcome to my Flask app!'

結果: 期待される表示は、http://localhost:5000にアクセスしたときにWelcome to my Flask app!が表示される状態です。

この段階ではHTMLファイルもデータベースも不要です。PythonとFlaskの関係を確認した後、render_templateを使って画面を分離します。画面の分離ができると、Web開発らしい構成へ移れます。

ルーティングとビュー関数

ルーティングは、URLパスとビュー関数を結び付ける仕組みです。Flaskでは@app.route('/path')を関数の直前に置き、アクセスされたパスに応じて処理を切り替えますし、これが一つの目安です。ビュー関数は、文字列、HTML、リダイレクト、JSONなどを返せます。

トップページ、ログインページ、ユーザー詳細ページは、異なるパスと関数で表現できます。Pythonの関数単位で処理を分けるため、プログラミングの基礎とWeb開発の構造が結び付きますが、覚えておくと役立つでしょう。

ルーティングの基本

ルートURLにアクセスされたときだけ応答する最小例は次の形です。/はサイトの入口を表すパスで、index関数が呼ばれます。戻り値の文字列がHTTPレスポンス本文になります。

from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
    return 'Hello, Flask!'

結果: 期待される表示は、トップページでHello, Flask!という文字列が返る状態です。

ビュー関数の作成

ビュー関数は、指定されたURLに対応するPython関数です。単純な文字列だけでなく、データベースから値を取り出してテンプレートへ渡す処理も担います。処理が増えすぎる場合は、モデルやサービス層へ分けます。

@app.route('/hello')
def hello():
    return 'Hello, User!'

結果: 期待される表示は、/helloへアクセスしたときにHello, User!が返る状態です。

サンプルコード3:ルーティングとビュー関数

複数のURLを扱うと、ルーティングの役割がはっきりすると考えられます。静的なパスだけでなく、<username>のような変数部分を持つ動的ルーティングも使えます。ユーザー名や記事IDをURLから受け取る形です。

from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
    return 'This is the index page.'

@app.route('/hello')
def hello():
    return 'Hello, User!'

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

結果: 期待される表示は、/user/johnへアクセスしたときにUser johnが返る状態です。

この仕組みを使うと、ユーザー別ページや記事詳細ページを少ないコードで表現できます。URLから受け取った値をそのまま信頼せず、データベース照合や認可チェックも組み合わせます。

テンプレートの利用

テンプレートは、Pythonの処理とHTMLの見た目を分けるために使いると言えるでしょう。FlaskではJinja2が標準的に組み込まれ、{{ username }}の変数埋め込みや{% for %}の繰り返しが使えます。Web開発では、画面が増えるほどテンプレート分離が効きますが、覚えておくと役立つでしょう。

ビュー関数はデータを準備し、テンプレートは表示を担当します。初心者はPythonの変数とJinja2の変数を混同しやすいため、render_templateに渡した名前だけがテンプレート側で使えると整理するのが基本です。

テンプレートの基本

テンプレートファイルは通常、templatesフォルダに置きます。render_template('index.html', username='John Doe')のように呼ぶと、Flaskがtemplates/index.htmlを探してレンダリングします。ファイル名やフォルダ名を間違えるとTemplateNotFoundになるのが基本です。

HTML内の見出し、一覧、フォームなどをテンプレートへ移せますし、ここを基本と考えるとよいでしょう。Python側ではデータ取得や判定に集中し、HTML側では表示構造を整えます。文字列処理はPythonで改行あり・なしを制御する方法も参考になるのが目安です。

Jinja2テンプレートエンジンの基本

Jinja2では、{{ }}が値の出力、{% %}が制御構文に使われます。{% if user %}でログイン状態に応じた表示を切り替え、{% for item in items %}で一覧を描画できるのが目安です。テンプレートに複雑な計算を書きすぎると保守しにくくなるのがポイントです。

計算やデータ加工はビュー関数側で済ませ、テンプレートには表示に必要な値だけを渡します。Flaskのテンプレートは自動エスケープに対応しますが、HTMLを意図的に出す場合はsafeフィルタのリスクを理解します。入力値を出力する画面ではセキュリティが欠かせません。

サンプルコード4:テンプレートの利用

次のサンプルコードでは、ビュー関数からindex.htmlusernameを渡するのがポイントです。Python側は値を準備し、HTMLの構造はテンプレートファイルに置きます。この分け方は、画面が増えたときにも読みやすくなるのが一般的です。

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html', username='John Doe')

結果: 期待される表示は、index.html内でusernameJohn Doeとして扱われる状態です。

対応するテンプレートは次のように書けます。{{ username }}の部分が、ビュー関数から渡された値に置き換わりますし、ここがポイントです。HTMLファイルはtemplates/index.htmlとして保存するのが現実的です。

<!doctype html>
<html>
<head>
    <title>Welcome!</title>
</head>
<body>
    <h1>Hello, {{ username }}!</h1>
</body>
</html>

結果: 期待される表示は、ブラウザ上の見出しにHello, John Doe!が表示される状態です。

これで、Pythonの値をHTMLへ渡す最小の流れが成立します。Web開発では、この仕組みで一覧、詳細、検索結果、エラーメッセージなどを表示します。サンプルコードを発展させるなら、usernameをフォーム入力やデータベースの値に置き換えますし、ここを基本と考えるとよいでしょう。

データベースとFlask-SQLAlchemy

Webアプリでは、ユーザー、投稿、注文、設定などを保存するのが一般的です。PythonとFlaskだけでもファイル保存はできますが、検索、更新、関連付けを扱うならデータベースを使います。Flask-SQLAlchemyは、SQLAlchemyをFlask向けに扱いやすくする拡張です。

Flask-SQLAlchemyはFlaskアプリでSQLAlchemyを使うための共通パターンを提供します。ORMを使うと、テーブルをPythonのクラスとして表現できるのが現実的です。ただし、SQLの考え方が不要になるわけではありません。

データベースの基本

リレーショナルデータベースは、データを表形式で保存し、行と列で管理します。idのような主キーで行を識別し、usernameemailの列に値を入れます。アプリ側のモデル設計は、画面やフォームより前に考える価値があると整理できると整理できます。

NoSQLデータベースは文書型やキー値型など別の表現を使います。Flaskの学習初期では、SQLiteとORMで小さく始めると、ファイルひとつでデータ保存を確認できます。PythonのプログラミングとSQLの関係を学ぶ入門としても扱いやすい選択です。

Flask-SQLAlchemyの基本

Flask-SQLAlchemyでは、db = SQLAlchemy()またはdb = SQLAlchemy(app)で拡張を初期化すると理解できます。モデルはdb.Modelを継承し、列はdb.Columnで定義します。db.Stringdb.Integerdb.Booleanなどの型と制約を合わせて書きますし、ここがポイントです。

本格運用では、テーブル作成や変更を手作業で管理すると破綻しやすくなります。Flask-Migrateのようなマイグレーションツールを使い、スキーマ変更を履歴として残すると覚えるとよいでしょう。学習段階ではdb.create_all()で構造を作る例から理解すると理解できます。

サンプルコード5:データベースとFlask-SQLAlchemyの利用

次のサンプルコードは、ユーザーを表すモデルを作る最小例です。SQLALCHEMY_DATABASE_URIにSQLiteの保存先を入れ、Userクラスで列を定義します。__repr__はデバッグ表示用の文字列を返すると考えられます。

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)

    def __repr__(self):
        return '<User %r>' % self.username

結果: 期待される状態は、Userモデルとしてidusernameemailの列定義を持つテーブル構造を表現できることです。

テーブルを作成するには、アプリケーションコンテキスト内でdb.create_all()を呼びます。Flask 3系では暗黙の状態利用を避け、with app.app_context()で範囲を示します。次のコードは学習用の作成例です。

with app.app_context():
    db.create_all()

結果: 期待される状態は、設定したSQLiteファイルにuserテーブル相当の構造が作成されることです。

Pythonのクラスを変更しても、既存テーブルが自動で安全に変更されるとは限りません。公開を考えるならマイグレーションを導入すると言えるでしょう。表操作に関心がある場合は、Pythonで表を操作するための詳細ガイドも補助資料になります。

フォームとFlask-WTF

フォームは、ユーザーが文字列、選択肢、チェック状態などを送る入口です。Flaskではrequest.formを直接読めますが、入力検証やCSRF対策を考えるとFlask-WTFが選択肢になります。Flask-WTFでは、WTFormsとの連携が説明されているのが基本です。

初心者がフォームでつまずきやすいのは、GET表示とPOST送信が同じURLで扱われる点です。ページを開くときはGET、送信するときはPOSTになり、ビュー関数内で分岐します。methods=['GET', 'POST']validate_on_submit()の組み合わせを理解します。

フォームの基本

フォーム処理では、入力項目の定義、HTMLへの描画、送信データの検証、保存や表示を扱いるのが目安です。名前、メールアドレス、パスワードなどは検証ルールが異なります。Python側で検証し、テンプレート側でエラーを表示すると修正しやすくなると覚えるとよいでしょう。

ブラウザの入力制限だけに頼るのは危険です。HTMLのrequiredtype='email'は補助であり、サーバー側でも検証します。Web開発では、クライアント側の値は書き換えられる可能性があるものとして扱いるのがポイントです。

Flask-WTFの基本

Flask-WTFを使うには、SECRET_KEYを設定し、CSRF保護を有効にします。CSRFProtect(app)はアプリ全体のフォーム送信に対してトークン確認を行います。秘密鍵は固定の例を公開環境で使わず、環境変数から読み込みますが、これは押さえたい点です。

from flask import Flask
from flask_wtf import CSRFProtect

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'
CSRFProtect(app)

結果: 期待される状態は、FlaskアプリにCSRF保護が組み込まれ、フォーム送信時にトークン確認が行われることです。

💡 Tips: SECRET_KEYは、セッション署名やCSRF保護に関わる値です。公開リポジトリへ直接書かず、os.environや設定ファイル管理を使うほうが運用しやすくなります。

サンプルコード6:フォームとFlask-WTFの利用

名前入力フォームでは、フォームクラスを定義してからビュー関数で使います。FlaskFormを継承し、StringFieldSubmitFieldを属性として置きますが、これは押さえたい点です。サンプルコードでは最小構成にし、バリデータは必要に応じて追加すると考えられます。

from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField

class NameForm(FlaskForm):
    name = StringField('名前を入力してください')
    submit = SubmitField('送信')

結果: 期待される状態は、名前入力欄と送信ボタンを持つNameFormクラスが定義されることです。

ビュー関数ではフォームを生成し、送信が有効なら入力値を取り出します。flashで一時メッセージを保存し、redirectで同じ画面へ戻すと、更新時の二重送信を避けやすくなるのが一般的です。url_forは関数名からURLを組み立てますし、これが一つの目安です。

from flask import render_template, flash, redirect, url_for

@app.route('/', methods=['GET', 'POST'])
def index():
    form = NameForm()
    if form.validate_on_submit():
        name = form.name.data
        flash('こんにちは、{}さん!'.format(name))
        return redirect(url_for('index'))
    return render_template('index.html', form=form)

結果: 期待される表示は、送信された名前を使ったメッセージが次の画面表示で確認できる状態です。

テンプレート側では、form.hidden_tag()でCSRFトークンを含む隠しフィールドを出します。form.name()form.submit()で入力欄とボタンを描画できます。Jinja2のループでget_flashed_messages()を表示すれば、送信後のメッセージも出せますが、覚えておくと役立つでしょう。

<!DOCTYPE html>
<html lang='ja'>
<head>
    <meta charset='UTF-8'>
    <title>名前入力フォーム</title>
</head>
<body>
    {% for message in get_flashed_messages() %}
    <div>{{ message }}</div>
    {% endfor %}

    <form method='POST'>
        {{ form.hidden_tag() }}
        {{ form.name.label }} {{ form.name() }}
        {{ form.submit() }}
    </form>
</body>
</html>

結果: 期待される表示は、名前入力フォームと送信ボタンが表示され、送信後にフラッシュメッセージが見える状態です。

ユーザ認証とFlask-Login

ユーザ認証は、ログインした人だけが利用できる画面を作る仕組みです。Flask-Loginは、ログイン状態の保持、現在のユーザー取得、ログイン必須ルートの保護を担います。パスワード登録、ハッシュ化、権限設計まですべてを自動で作るわけではありません。

認証を入れるときはモデル、フォーム、ビュー、テンプレートをまとめて考えます。PythonのコードではUserMixinLoginManagerlogin_userlogout_usercurrent_userなどが登場するのが現実的です。Web開発の中でもセキュリティに直結する領域です。

ユーザ認証の基本

認証では、ユーザーが入力した識別子とパスワードを保存済み情報と照合します。保存時には平文で持たず、generate_password_hashでハッシュ化し、照合時にcheck_password_hashを使います。メール確認や多要素認証などは別の仕組みとして設計すると言えるでしょう。

初心者が注意したいのは、ログインできることと安全に運用できることは別だという点です。サンプルコードは動きの理解に使い、公開時にはHTTPS、セッション設定、レート制限、パスワード再設定手順も検討すると整理できます。Flask-Loginはセッション管理を補助しますが、認可設計はアプリ側の責務です。

Flask-Loginの基本

Flask-Loginを使うモデルでは、ユーザーIDを返せることが前提です。UserMixinを継承すると、よく使うプロパティの既定実装を利用できます。次の例では、パスワードハッシュを保存し、照合用のメソッドを持たせています。

class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), index=True, unique=True)
    password_hash = db.Column(db.String(128))

    def check_password(self, password):
        return check_password_hash(self.password_hash, password)

    def set_password(self, password):
        self.password_hash = generate_password_hash(password)

結果: 期待される状態は、ユーザー名とパスワードハッシュを持ち、パスワード設定と照合ができるモデルになることです。

サンプルコード7:ユーザ認証とFlask-Loginの利用

ログイン管理を始めるには、LoginManagerをアプリに関連付け、ユーザーIDからユーザーを復元する関数を登録します。セッションにはユーザーIDが保存され、リクエストごとにローダ関数が呼ばれます。次のサンプルコードではUser.query.getで取得するのが基本です。

from flask_login import LoginManager

login = LoginManager(app)

@login.user_loader
def load_user(id):
    return User.query.get(int(id))

結果: 期待される状態は、Flask-Loginがセッション内のユーザーIDから対応するUserオブジェクトを復元できることです。

ログインとログアウトのルートでは、フォーム入力を検証し、ユーザーが存在してパスワードが合う場合だけlogin_userを呼びます。ログアウトにはlogout_userを使い、保護したいURLには@login_requiredを付けます。認証失敗時は同じログイン画面へ戻するのが目安です。

from flask import redirect, url_for, flash, render_template
from flask_login import login_user, logout_user, login_required

@app.route('/login', methods=['GET', 'POST'])
def login_view():
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        if user is None or not user.check_password(form.password.data):
            flash('Invalid username or password')
            return redirect(url_for('login_view'))
        login_user(user, remember=form.remember_me.data)
        return redirect(url_for('index'))
    return render_template('login.html', title='Sign In', form=form)

@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('index'))

結果: 期待される状態は、有効な認証情報でログインし、保護されたログアウトURLからセッションを終了できることです。

この構成では、ログイン処理の流れがビュー関数内に集まります。登録、権限、プロフィール編集が増えると、フォームやサービスを分けるほうが扱いやすくなります。PythonのWeb開発では、最初に動く形を理解し、その後に責務を分割するのがポイントです。

デプロイとFlaskの運用

デプロイは、開発したFlaskアプリを利用者がアクセスできる環境へ配置する作業です。ローカルのflask runは開発用であり、本番運用ではGunicornやuWSGIなどのWSGIサーバーを使いると理解できます。設定値、依存関係、ログ、静的ファイル、データベース接続を確認します。

公開環境ではDEBUGを無効にし、SECRET_KEYやデータベースURLを環境変数で渡します。エラー詳細を外部へ出さないこと、HTTPSを使うこと、ログに個人情報を出しすぎないことも大切です。Web開発の学習ガイドでは、ローカル成功と本番運用の違いを早めに理解すると覚えるとよいでしょう。

デプロイの基本

デプロイ準備では、コード、依存関係、起動コマンド、環境変数をそろえます。requirements.txtには必要なパッケージを記録し、サーバー側ではpip install -r requirements.txtで再現します。データベースを使う場合は、接続先とマイグレーション手順も必要です。

サーバーやクラウドサービスによって設定方法は異なると考えられます。PaaSでは起動コマンドを管理画面へ書く場合があり、VPSではsystemdやNginxを組み合わせる場合があります。Pythonアプリの公開では、アプリ本体だけでなく周辺設定も運用品質に影響するのが一般的です。

Flaskアプリの運用

Flaskアプリの運用では、プロセス管理、ログ監視、バックアップ、依存関係更新を継続して扱います。小さな個人用アプリでも、データベースのバックアップと秘密情報の管理は欠かせません。学習目的の一時公開なら、無料枠の制約やスリープ仕様も確認すると言えるでしょう。

FLASK_ENVに頼る古い説明ではなく、現在のFlaskに合う設定方法を確認します。app.config.from_prefixed_env()などを使う構成もありますが、最初は環境変数から値を読み込むだけでも整理できます。自動化に関心がある場合は、Pythonで実現するウィンドウ操作の自動化も応用例になるのが現実的です。

サンプルコード8:デプロイと運用

GunicornでFlaskアプリを起動する場合、モジュール名とアプリケーション変数名をmyapp:appの形で渡するのが基本です。-w 4はワーカープロセス数を表し、CPUやメモリに応じて調整します。次のコマンドは基本形です。

gunicorn -w 4 myapp:app

結果: 期待される状態は、myapp.py内のappをGunicornが読み込み、WSGIサーバーとしてリクエストを受けられることです。

このコマンドだけで公開全体が完了するわけではありません。実際の公開では、リバースプロキシ、TLS証明書、ログ出力、プロセス再起動、静的ファイル配信も組み合わせます。PythonとFlaskのサンプルコードが動いた後は、運用環境の責務を分けて確認するのが目安です。

ℹ️ 補足: グラフや管理画面を加えるアプリでは、表示用データの整形も発生すると覚えるとよいでしょう。Pythonで可視化する方向へ広げる場合は、Pythonで折れ線グラフ作成の完全ガイドも参考になります。

まとめ

PythonとFlaskでWebアプリを作る流れは、最小アプリ、ルーティング、テンプレート、データベース、フォーム、認証、デプロイへ広げると理解しやすくなります。Flaskは小さく始められる一方で、拡張を足すほど設計判断が増えますし、これが一つの目安です。初心者はサンプルコードの意味を確認しながら、責務をひとつずつ分ける進め方が合いると整理できます。

中核になるのは、Flask@app.routerender_templatedb.ModelFlaskFormLoginManagergunicornです。これらをつなげると、Pythonのプログラミング基礎がWeb開発の実装へ変わります。公開時にはセキュリティ、ログ、依存関係、バックアップも合わせて考えますが、覚えておくと役立つでしょう。

学習を続けるなら、小さなCRUDアプリを作り、ユーザー登録とログインを加え、公開環境への配置まで進める順番が現実的です。サンプルコードを写すだけでなく、文字列、URL、テンプレート変数、モデル名を少しずつ変えると理解が深まります。PythonとFlaskの学習ガイドとして、手元で読み替えながら進めます。

著者: Japanシーモア編集部

Japanシーモアは、Web/IoT/APP/SYS 分野のプログラミング情報を体系的に提供するメディアです。本記事は編集部による執筆とAI支援を組み合わせて制作し、公開前に編集部が校正しています。誤りや改善案がございましたらお問い合わせよりご連絡ください。

※本記事は実在のエンジニア複数名で構成される Japanシーモア編集部が、AI支援を活用して作成・校正・公開しています。

関連記事