ななぶろ

-お役立ち情報を気楽に紹介するブログ-

Python Flaskプログラム練習問題10選:Webアプリケーション開発の基礎を習得しよう!

www.amazon.co.jp

Flaskプログラム練習問題10選:Webアプリケーション開発の基礎を習得しよう!

PythonとFlaskは、Webアプリケーション開発において非常に強力な組み合わせです。Pythonはそのシンプルさと豊富なライブラリによって、初心者にも扱いやすく、Flaskは軽量かつ柔軟なフレームワークとして、迅速なプロトタイピングや小規模から中規模のWebアプリケーションの開発に最適です。

本記事では、Flaskを効果的に学習するための練習問題10選を紹介します。これらの問題を解くことで、Flaskの基本的な概念から応用的な機能まで、段階的に習得することができます。各問題には解説とサンプルコードも用意しているので、初心者の方でも安心して取り組めるはずです。

準備:開発環境の構築

まず、Flaskを始める前に、Pythonとpip(パッケージ管理システム)がインストールされていることを確認してください。まだインストールされていない場合は、以下の手順でインストールできます。

  1. Pythonのインストール: https://www.python.org/downloads/ から最新版のPythonをダウンロードし、指示に従ってインストールします。インストーラーを実行する際には、「Add Python to PATH」にチェックを入れることを推奨します。これにより、コマンドプロンプトやターミナルからPythonコマンドが実行できるようになります。
  2. pipの確認: コマンドプロンプトまたはターミナルで pip --version と入力し、pipが正しくインストールされているか確認します。pipはPythonパッケージを管理するためのツールです。もしpipがインストールされていない場合は、https://pip.pypa.io/en/stable/installation/ を参照してインストールしてください。

次に、Flaskをインストールします。コマンドプロンプトまたはターミナルで以下のコマンドを実行します。

pip install flask

Explanation: Before starting with Flask, ensure you have Python and pip installed. Download the latest version of Python from https://www.python.org/downloads/ and follow the installation instructions. Make sure to check "Add Python to PATH" during installation for easy access in your terminal. Verify pip by running pip --version. Then, install Flask using pip install flask.

練習問題1:Hello, World! - 基本的なWebアプリケーションの作成

目的: Flaskアプリケーションの基本的な構造を理解し、簡単なWebページを表示する。

解説: Flaskアプリケーションは、flask.Flask(__name__) でインスタンス化されます。__name__ は現在のモジュール名を表します。これはFlaskがアプリケーションのルートディレクトリを特定するために使用されます。@app.route() デコレーターを使って、URLと関数を結び付けます。このデコレーターによって、指定されたURLにアクセスされると、対応する関数が実行されます。return 文は、Webブラウザに返されるコンテンツを指定します。

サンプルコード:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "Hello, World!"

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

実行方法: 上記のコードを hello.py という名前で保存し、コマンドプロンプトまたはターミナルで python hello.py と入力して実行します。ブラウザで http://127.0.0.1:5000/ にアクセスすると "Hello, World!" と表示されます。debug=True は開発モードを有効にし、コードの変更が自動的に反映されるようにし、エラーが発生した場合に詳細な情報が表示されるようになります。

Explanation: The first step is to create a Flask application instance using flask.Flask(__name__). The @app.route("/") decorator maps the root URL ("/") to the hello_world() function. When you access this URL in your browser, the hello_world() function will be executed and return "Hello, World!". Save the code as hello.py, run it with python hello.py, and then visit http://127.0.0.1:5000/ in your browser to see the result. The debug=True argument enables debug mode for easier development.

練習問題2:変数の受け渡し - URLパラメータの利用

目的: URLからパラメータを受け取り、Webページに表示する。

解説: Flaskでは、URLパラメータを <variable_name> の形式で指定することで、関数に渡すことができます。例えば、/hello/<name> というルートは、name というパラメータを受け取ります。request.args 属性を使って、URLパラメータの値を取得します。request.args はGETリクエストのクエリパラメータを格納する辞書です。

サンプルコード:

from flask import Flask, request

app = Flask(__name__)

@app.route("/hello/<name>")
def hello_name(name):
    return f"Hello, {name}!"

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

実行方法: 上記のコードを hello_name.py という名前で保存し、コマンドプロンプトまたはターミナルで python hello_name.py と入力して実行します。ブラウザで http://127.0.0.1:5000/hello/Taro にアクセスすると "Hello, Taro!" と表示されます。

Explanation: This problem demonstrates how to pass parameters in the URL. The @app.route("/hello/<name>") decorator defines a route that accepts a parameter named name. The value of this parameter is passed as an argument to the hello_name() function. You can access the parameter's value using request.args['name'], but in this case, it's directly available as the name argument. Visit http://127.0.0.1:5000/hello/Taro to see "Hello, Taro!".

練習問題3:GETとPOSTリクエストの処理 - フォームデータの送信

目的: GETリクエストとPOSTリクエストを区別し、それぞれの方法でデータを処理する。

解説: GETリクエストはURLにパラメータを含めて送信されるため、データ量が少なく、冪等性(同じリクエストを何度実行しても結果が変わらないこと)を持つ操作に適しています。一方、POSTリクエストはHTTPボディにデータを格納して送信するため、大量のデータや機密性の高い情報を送信するのに適しています。request.method 属性を使って、リクエストの種類を確認できます。フォームからデータを送信する場合、通常はPOSTリクエストを使用します。

サンプルコード:

from flask import Flask, request, render_template

app = Flask(__name__)

@app.route("/", methods=["GET", "POST"])
def index():
    if request.method == "POST":
        name = request.form["name"]
        return f"Hello, {name}!"
    else:
        return render_template("index.html")

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

テンプレートファイル (index.html):

<!DOCTYPE html>
<html>
<head>
    <title>Index</title>
</head>
<body>
    <h1>Enter your name:</h1>
    <form method="POST">
        <input type="text" name="name">
        <button type="submit">Submit</button>
    </form>
</body>
</html>

実行方法: 上記のコードを index.py という名前で保存し、テンプレートファイル index.html を同じディレクトリに作成します。コマンドプロンプトまたはターミナルで python index.py と入力して実行します。ブラウザで http://127.0.0.1:5000/ にアクセスするとフォームが表示されます。名前を入力して送信すると、"Hello, [入力した名前]!" と表示されます。

Explanation: This problem demonstrates handling GET and POST requests. The @app.route("/", methods=["GET", "POST"]) decorator allows the route to handle both types of requests. The if request.method == "POST": block checks if the request is a POST request (typically from submitting a form). If it is, the code retrieves the value of the 'name' field from the form data using request.form["name"]. Otherwise, it renders the index.html template, which displays the form.

練習問題4:テンプレートエンジンの利用 - HTMLの動的な生成

目的: Jinja2テンプレートエンジンを使って、HTMLを動的に生成する。

解説: FlaskはデフォルトでJinja2テンプレートエンジンを使用します。テンプレートファイルには、変数や制御構造(if文、for文など)を含めることができ、Pythonコードから渡されたデータに基づいて動的に生成されます。render_template() 関数を使って、テンプレートファイルをレンダリングします。テンプレートファイルは通常、.html 拡張子を持ちます。

サンプルコード: 練習問題3の index.py を参照してください。

Explanation: Jinja2 is Flask's default templating engine. It allows you to create dynamic HTML pages by embedding variables and control structures within your templates. The render_template() function renders the template file, replacing placeholders with data passed from the Python code. The index.html file in this example demonstrates how to display a form.

練習問題5:セッション管理 - ユーザーの状態を保持する

目的: セッションを使って、ユーザーの状態(ログイン状態など)を保持する。

解説: セッションは、Webサーバーがクライアント(ブラウザ)に対して特定の情報を記憶させる仕組みです。Flaskでは、session オブジェクトを使ってセッションデータを管理します。セッションデータは通常、クッキーまたはサーバー側のデータベースに保存されます。セキュリティのため、セッションキーを設定することが重要です。

サンプルコード:

from flask import Flask, session, redirect, url_for, request

app = Flask(__name__)
app.secret_key = "your secret key"  # セッションを暗号化するためのキーを設定

@app.route("/")
def index():
    if 'username' in session:
        return f"Logged in as {session['username']}"
    else:
        return "<a href='/login'>Login</a>"

@app.route("/login", methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username']
        return redirect(url_for('index'))
    return """
        <form method="post">
            Username: <input type="text" name="username"><br>
            <button type="submit">Login</button>
        </form>
    """

@app.route("/logout")
def logout():
    session.pop('username', None)
    return redirect(url_for('index'))

実行方法: 上記のコードを session_example.py という名前で保存し、コマンドプロンプトまたはターミナルで python session_example.py と入力して実行します。ブラウザで http://127.0.0.1:5000/ にアクセスするとログインページが表示されます。ユーザー名を入力してログインすると、セッションが確立され、ログイン状態が表示されます。

Explanation: This problem demonstrates session management in Flask. The app.secret_key = "your secret key" line sets a secret key that is used to encrypt the session data. It's crucial to change this to a strong, random value in production. The /login route handles both GET (displaying the login form) and POST (processing the submitted username). The session['username'] = request.form['username'] line stores the username in the session. The /logout route removes the username from the session.

練習問題6:データベース連携 - SQLiteを使ったデータの保存と取得

目的: SQLiteデータベースを使って、データを保存し、取得する。

解説: SQLiteは軽量なファイルベースのデータベースです。Flaskでは、flask_sqlalchemy 拡張機能を使うことで、簡単にSQLiteデータベースを操作できます。flask_sqlalchemy はSQLAlchemy ORM(Object-Relational Mapper)を提供し、Pythonオブジェクトを使ってデータベーステーブルを操作できるようにします。

サンプルコード:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'  # SQLiteデータベースのパスを設定
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))

    def __repr__(self):
        return f'<User {self.username}>'

@app.route("/")
def index():
    users = User.query.all()
    return render_template("index.html", users=users)

if __name__ == "__main__":
    with app.app_context():
        db.create_all()  # データベーステーブルを作成
    app.run(debug=True)

テンプレートファイル (index.html):

<!DOCTYPE html>
<html>
<head>
    <title>Users</title>
</head>
<body>
    <h1>Users</h1>
    <ul>
        {% for user in users %}
            <li>{{ user.username }} - {{ user.email }}</li>
        {% endfor %}
    </ul>
</body>
</html>

実行方法: 上記のコードを database_example.py という名前で保存し、テンプレートファイル index.html を同じディレクトリに作成します。コマンドプロンプトまたはターミナルで python database_example.py と入力して実行します。ブラウザで http://127.0.0.1:5000/ にアクセスすると、ユーザー一覧が表示されます(初期状態では空)。

Explanation: This problem demonstrates how to connect a Flask application to an SQLite database using the flask_sqlalchemy extension. The User class defines a table in the database with columns for id, username, and email. The db.create_all() line creates the table if it doesn't already exist. The / route queries all users from the database and passes them to the index.html template.

練習問題7:RESTful APIの作成 - JSONデータの送受信

目的: RESTful APIを作成し、JSON形式でデータを送受信する。

解説: RESTful APIは、Webサービスを構築するための設計スタイルです。Flaskでは、jsonify() 関数を使ってPythonオブジェクトをJSON形式に変換し、request.get_json() メソッドを使ってJSONリクエストボディからデータを取得できます。HTTPメソッド(GET, POST, PUT, DELETE)を使って、データの取得、作成、更新、削除を行います。

サンプルコード:

from flask import Flask, jsonify, request

app = Flask(__name__)

@app.route("/api/users", methods=["GET"])
def get_users():
    users = [
        {"id": 1, "username": "Taro"},
        {"id": 2, "username": "Hanako"}
    ]
    return jsonify(users)

@app.route("/api/users", methods=["POST"])
def create_user():
    data = request.get_json()
    username = data["username"]
    # ここでデータベースにユーザーを保存する処理を追加
    return jsonify({"message": f"User {username} created successfully!"}), 201

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

Explanation: This problem demonstrates how to create a RESTful API in Flask. The /api/users route handles both GET (retrieving all users) and POST (creating a new user) requests. The jsonify() function converts the Python list of dictionaries into a JSON response. The request.get_json() method parses the JSON data from the request body.

練習問題8:エラーハンドリング - 例外の捕捉と表示

目的: 例外を捕捉し、ユーザーに適切なエラーメッセージを表示する。

解説: Flaskでは、@app.errorhandler() デコレーターを使って、特定のHTTPエラーコード(404 Not Foundなど)や例外を処理するための関数を定義できます。これにより、アプリケーションがクラッシュすることなく、ユーザーに分かりやすいエラーメッセージを表示することができます。

練習問題9:ブループリントの利用 - アプリケーションのモジュール化

目的: アプリケーションを複数のブループリントに分割し、コードを整理する。

解説: ブループリントは、Flaskアプリケーションの一部をモジュール化するための仕組みです。ブループリントを使うことで、大規模なアプリケーションをより管理しやすくすることができます。各ブループリントは、独自のルーティング、テンプレート、静的ファイルなどを持ちます。

練習問題10:拡張機能の利用 - Flask-Loginを使った認証機能の実装

目的: Flask-Login 拡張機能を使って、ユーザー認証機能を実装する。

解説: Flask-Login は、ユーザーログインとログアウトを簡単に行うための拡張機能です。この拡張機能を使うことで、ユーザーの認証状態を管理し、保護されたページへのアクセス制御を行うことができます。