見出し画像

Pythonでステップバイステップ!Flaskによるブログ作成シリーズ第1弾

Python はデータ分析や AI の分野でよく知られていますが、その柔軟性とパワーはウェブシステム構築にも活かすことができます。
PHP など他の言語と比較しても、Python のコードは簡潔であり、豊富なフレームワークがその開発をさらにスムーズにします。

そこで、このシリーズでは、小規模開発に特に適した Python のフレームワーク「Flask」を使用し、ステップバイステップでブログシステムを構築していきます。

大規模開発向けの Django については、このシリーズの後に探求していく予定です。

今回の冒険では、Windows 11 環境で Python 3.11 が正しくインストールされていることを前提とし、VSCode があればなお作業がしやすくなります。

私も学習しながら進めていきますので、更新頻度はゆっくりです。


仮想環境を構築します

作業するディレクトリを用意します。
ディレクトリを決めたらディレクトリをカレントディレクトリーとし、次のコマンドを実行します。
ここでは仮想環境名を「flaskenv」としていします。

python -m venv flaskenv

仮想環境の有効化を行います

同じディレクトリで次のコマンドを入力し実行してください。

  • Windowsの場合: flaskenv\Scripts\activate

  • macOS/Linuxの場合: source flaskenv/bin/activate

仮想環境名が flaskenv で進めていますので上記のようになっています。
環境に合わせて変更してください。

仮想環境が有効になると、ターミナルのプロンプトに仮想環境名が表示されます。これで、Flaskを含む必要なパッケージのインストールやアプリケーションの実行が、この仮想環境内で行われることになります。

作業用の「FlaskBlog」ディレクトリをカレントディレクトリにして、「python -m venv flaskenv」を実行しています。

Flaskのインストール: 仮想環境内でFlaskをインストールします

Flask の F は大文字です。注意して入力してください。

pip install Flask

Hello, World! で Flask の最初のアプリケーション作成

アプリケーションファイルの作成 app.py という名前のファイルを作成し、以下のコードを追加します。

from flask import Flask

app = Flask(__name__)

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

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

Hello, World! の app.py を実行

ターミナル上でプログラムを実行してください。
VSCodeのデバッグ機能などを使うとエラーになる場合があります。

python app.py

ブラウザで確認: アプリケーションが正しく実行されていることを確認するために、ブラウザを開き http://127.0.0.1:5000/ にアクセスします。"Hello, World!"が表示されれば成功です。

今日はログイン画面表示まで

1. ユーザー認証の実装

ブログの管理画面にアクセスできるのは、認証されたユーザー(例えば、あなたや他のブログ管理者)のみに限定することが一般的です。Flaskでは、Flask-LoginFlask-Securityといった拡張機能を利用してユーザー認証を実装できます。

2. ブログポストのモデル定義

データベースにブログポストを保存するために、ポストのモデルを定義します。これには、タイトル、本文、投稿日時などのフィールドが含まれます。Flask-SQLAlchemyはORM(Object-Relational Mapping)を提供し、このプロセスを簡単にします。

3. 管理画面のルーティングとビューの作成

管理画面用のURLを定義し(例: /admin)、それに対応するビュー関数を作成します。ビュー関数では、認証されたユーザーにのみアクセスを許可し、ブログポストのリスト表示、新規作成、編集、削除などのアクションを処理します。

4. フォームの作成

ブログポストの作成や編集には、ユーザーがデータを入力できるフォームが必要です。Flask-WTFは、フォームの生成とバリデーション(入力検証)を簡単にする便利な拡張機能です。

5. テンプレートの作成

管理画面の各ページ(ブログポストのリスト、新規作成フォーム、編集フォームなど)に対応するHTMLテンプレートを作成します。Jinja2テンプレートエンジンを使うことで、Pythonコードから動的にコンテンツを生成し、HTMLに埋め込むことができます。

6. スタイルとインタラクションの追加

CSSフレームワーク(例えばBootstrap)を使用して、管理画面の見た目を整えます。さらに、JavaScriptやAJAXを使って、ユーザーインタラクションを向上させることも考えられます。

このプロセスを進めることで、簡単なブログの管理画面を作成し、基本的なブログ機能を実装できます。管理画面が完成したら、公開用のブログページ(ホームページ、個別投稿ページなど)の開発に移ることができます。

ユーザー認証の機能(Flask-Login)

ユーザー認証を機能を Flask に実装するには、'Flask-Login' を使用して認証機能を実装します。

ステップ 1 Flask-Login のインストール

仮想環境が有効であることを確認し、'Flask-Login' をインストールします。

pip install Flask-Login

ステップ 2 ユーザーモデルの作成

ユーザー情報を格納するためのモデルを定義します。
Flask-SQLAlchemyを使用してデータベースモデルを作成します。
Flask-SQLAlchemyが未インストールの場合は、先にインストールしてください。

pip install Flask-SQLAlchemy

app.py を書き換えていきます(Hello, World! を残したい人はファイル名などを変更してください)。

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import UserMixin, LoginManager, login_user, login_required, logout_user, current_user

app = Flask(__name__)
# データベースと秘密鍵の設定
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///yourdatabase.db'
app.config['SECRET_KEY'] = 'yoursecretkey'

db = SQLAlchemy(app)
login_manager = LoginManager()
login_manager.init_app(app)

# ユーザモデルテー偽
class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(100), unique=True, nullable=False)
    password = db.Column(db.String(100), nullable=False)

# ユーザーローダーの定義
@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///yourdatabase.db'
app.config['SECRET_KEY'] = 'yoursecretkey'

yourdatabase.db, yoursecretkey は自由に変更してください。

yoursecretkeyは、Flaskアプリケーションがセッション情報を暗号化するために使用する秘密鍵です。これをランダムな値に設定することで、セキュリティを向上させることができます。

この秘密鍵はランダムな文字列であるべきです。実際に設定する際には、例えばPythonのos.urandom()関数を使用して生成することができます。

import os

app.config['SECRET_KEY'] = os.urandom(32)

ただし、毎回異なる秘密鍵を生成すると、再起動するたびにセッションが無効になるため、開発中以外では固定の秘密鍵を使用することが推奨されます。

ステップ 3 ユーザー認証のルートとビューの作成

ログインページとログアウト機能を持つシンプルなビューを作成します。

# 既にあるコード (ユーザーモデル定義など)

from flask import render_template, request, redirect, url_for
from werkzeug.security import generate_password_hash, check_password_hash

# ユーザーローダーの設定
@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

# ログインページ
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        user = User.query.filter_by(username=username).first()
        
        if user and check_password_hash(user.password, password):
            login_user(user)
            return redirect(url_for('dashboard'))
        else:
            return 'Login Failed'
    return render_template('login.html')

# ダッシュボード(認証後のページ)
@app.route('/dashboard')
@login_required
def dashboard():
    return 'Welcome to the Dashboard'

# ログアウト
@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('login'))

# データベースの作成
if __name__ == '__main__':
    with app.app_context():
        db.create_all()
    app.run(debug=True)

app.py に ステップ 2 とステップ 3 のコードを後ほどマージしますが、ステップ 3 のコードはまだ完成していません。

ステップ 4 『ステップ2 と 3』 のコードを app.py にマージする

from 文は上部にまとめる。
from 文は複数箇所に散らばっていても機能はします。Python では必要なモジュールや関数を必要な時点でインポートできるからです。
Python の柔軟性が高いことが特徴の 1 つだからです。

ただし、コードの可読性や保守性の観点からは、ファイルの上部にインポート文をまとめることが一般的な慣習です。これにより、他の開発者がコードを見たときに、どの外部モジュールや関数が使用されているかをすぐに理解できるため、コードの理解が容易になります。

インポート文を上部にまとめることで、コードの整理と可読性が向上します。

from flask import Flask, render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
from flask_login import UserMixin, LoginManager, login_user, login_required, logout_user, current_user
from werkzeug.security import generate_password_hash, check_password_hash


app = Flask(__name__)
# データベースと秘密鍵の設定
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///yourdatabase.db'
app.config['SECRET_KEY'] = 'yoursecretkey'

db = SQLAlchemy(app)
login_manager = LoginManager()
login_manager.init_app(app)
 #ユーザモデル定義 
class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(100), unique=True, nullable=False)
    password = db.Column(db.String(100), nullable=False)

# ユーザーローダーの設定
@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

# ホームページへのアクセスをログインページへリダイレクト
@app.route('/')
def redirect_to_login():
    return redirect(url_for('login'))

# ログインページ
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        user = User.query.filter_by(username=username).first()
        
        if user and check_password_hash(user.password, password):
            login_user(user)
            return redirect(url_for('dashboard'))
        else:
            return 'Login Failed'
    return render_template('login.html')

# ダッシュボード(認証後のページ)
@app.route('/dashboard')
@login_required
def dashboard():
    return 'Welcome to the Dashboard'

# ログアウト
@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('login'))

# データベースの作成
if __name__ == '__main__':
    with app.app_context():
        db.create_all()
    app.run(debug=True)

ステップ 5 プロジェクトの Tree 構造

ここでファイル構造を若干整理しておきます。
Flask のフォルダーなどは除いて、ユーザーが今後作業する上で重要な部分だけ示しておきます。

下記の通り、templates フォルダを用意して、フォルダー内に login.html を作成してください。

基本プロジェクトフォルダ/
│
├── app.py
└── templates/
    └── login.html

ステップ 6 ログインフォームの作成

初歩的な HTML コードだけでシンプルなフォームを用意します。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login</title>
</head>
<body>
    <form action="" method="post">
        Username: <input type="text" name="username"><br>
        Password: <input type="password" name="password"><br>
        <input type="submit" value="Login">
    </form>
</body>
</html>

app.py を実行する

これで、ログイン機能を含む基本的なユーザー認証システムがFlaskアプリケーションに組み込まれます。このコードには、パスワードをハッシュ化して保存する処理は含まれていませんので、実際のユーザー登録時にはパスワードを適切にハッシュ化する処理を追加する必要があります。

コマンドを入力して実行します。

python app.py

ブラウザを起動して、' http://127.0.0.1:5000/login ' にアクセスしてください。

次のように表示されれば成功です。
お疲れ様でした。
長くなりましたので、第1回目はここまでで終了します。

python app.py の実行結果です

まとめ

今回の冒険では、PythonとそのスマートなウェブフレームワークFlaskを使って、ブログシステムの骨組みに火をつけました。初めての「Hello, Flask!」から、環境設定、そして仮想環境 flaskenv の準備まで、基礎をしっかりと固めてスタートしました。

そして、私たちはさらに一歩踏み出し、Flask-LoginとFlask-SQLAlchemyを使って、ブログシステムにユーザー認証の土台を築き始めました。パスワードのハッシュ化と秘密鍵の管理により、セキュリティの基礎を学びましたが、まだテスト段階です。完璧ではないにせよ、これらの技術によってブログシステムは次のレベルへと進みつつあります。

このシリーズの最初の記事で、Flaskでのウェブ開発の扉を開けました。まだ認証機能は完成形には至っていませんが、この過程を通じて、あなたもウェブ開発の基本を楽しみながら学べるはずです。さあ、PythonとFlaskの力を信じ、次回のさらなる冒険に備えましょう。ウェブ開発の世界は広大で、学ぶべきことがまだまだたくさんあります!




この記事が気に入ったらサポートをしてみませんか?