Flaskフレームワーク:リクエストとレスポンス & テンプレート構文

Flaskフレームワーク:リクエストとレスポンス & テンプレート構文

Flaskフレームワークの基本

FlaskはPythonで書かれた軽量級のカスタマイズ可能なフレームワークです。他の同種のフレームワークと比較して、より柔軟、軽量、安全で学習が容易です。

MVCパターンと良好に連携して開発でき、開発者間での協力が可能です。小規模なチームでも短期間で機能豊富な中小規模のWebサイトやWebサービスを実装できます。

また、Flaskは高いカスタマイズ性を持ち、ユーザーは自身のニーズに応じて対応する機能を追加できます。コア機能をシンプルに保ちながら、機能の豊富化と拡張を実現します。

FlaskとDjangoの比較

Djangoフレームワーク Flask Webフレームワーク
豊富なネイティブコンポーネント
教科書的なフレームワーク
ORM機能
Formコンポーネント
セッションモデル
管理画面とCSRF保護
非常に簡潔で軽量
最小限のセッション機能
包括的なサードパーティコンポーネント
欠点: 大規模なロード項目、リソースの浪費
適用: 大規模、高密度プロジェクト
欠点: サードパーティコンポーネントの実行安定性が相対的に低い
適用: 小規模、APIサービスプロジェクト

Flaskの基本的な使用方法

# Flaskサービスを3行で起動
from flask import Flask
app = Flask(__name__)
app.run()

FlaskのResponse(レスポンス)

文字列を返す

@app.route("/index")
def index():
    return "こんにちは、世界!"  # DjangoのHttpResponseに相当

HTMLテンプレートをレンダリング

# HTMLコード
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>テンプレート例</title>
</head>
<body>
    <h1>こんにちは</h1>
</body>
</html>

# Pythonコード
from flask import Flask, render_template

app = Flask(__name__)

@app.route("/home")
def home():
    return render_template("home.html")  # テンプレートはtemplatesディレクトリに配置

リダイレクト

from flask import Flask, render_template, redirect

app = Flask(__name__)

@app.route("/home")
def home():
    return render_template("home.html")  

@app.route("/redirect_example")
def redirect_example():
    return redirect("/home")  # homeにリダイレクト

リダイレクトは、ResponseHeadersにLocationヘッダーを追加することで実現されます。

ファイルを返す

# 画像ファイルを返す例
from flask import Flask, send_file

app = Flask(__name__)

@app.route("/download_image")
def download_image():
    return send_file("sample.jpg")

send_fileはファイルを開いて内容を返し、Content-Typeヘッダーを自動的に追加します。認識できないファイルタイプはダウンロードとして処理されます。

JSON形式のデータを返す

from flask import Flask, jsonify

app = Flask(__name__)

@app.route("/api/user")
def get_user():
    user_data = {
        "name": "山田太郎",
        "age": 30
    }
    return jsonify(user_data)

jsonify()はJSONデータをシリアライズし、Content-Type: application/jsonヘッダーを追加します。APIインターフェースで一般的に使用されます。

FlaskのRequest(リクエスト)

リクエストメソッドの取得

@app.route("/handle_form", methods=['GET', 'POST'])
def handle_form():
    if request.method == 'GET':
        return render_template("form.html")
    
    if request.method == 'POST':
        # POSTリクエストの処理
        return "データを受け取りました"

フォームデータの取得

# HTMLフォーム
<form action="/submit" method="post">
  <p>ユーザー名: <input type="text" name="username"></p>
  <p>パスワード: <input type="password" name="password"></p>
  <input type="submit" value="送信">
</form>

# Pythonコード
@app.route("/submit", methods=['POST'])
def submit():
    username = request.form.get("username")
    password = request.form.get("password")
    return f"ユーザー名: {username}"

URLパラメータの取得

@app.route("/search")
def search():
    query = request.args.get('q')
    return f"検索キーワード: {query}"

リクエスト情報の取得

  • request.url: 完全なURL
  • request.url_root: ベースURL(ホスト名)
  • request.url_rule: ルートパス(パラメータなし)
  • request.path: リクエストパス
  • request.host: ホスト名
  • request.method: HTTPメソッド
  • request.headers: リクエストヘッダー
  • request.cookies: クッキー情報

ファイルのアップロード

# HTMLアップロードフォーム
<form action="/upload" method="post" enctype="multipart/form-data">
  <p><input type="file" name="uploaded_file"></p>
  <input type="submit" value="アップロード">
</form>

# Pythonコード
import os
from flask import Flask, request

app = Flask(__name__)

@app.route("/upload", methods=["GET", "POST"])
def upload_file():
    if request.method == 'GET':
        return render_template('upload.html')
    
    if request.method == 'POST':
        uploaded_file = request.files.get("uploaded_file")
        if uploaded_file:
            save_path = os.path.join("uploads", uploaded_file.filename)
            uploaded_file.save(save_path)
            return "ファイルアップロード成功"
        return "ファイルがありません"

Flaskテンプレート言語(Jinja2)

Jinja2はFlaskのデフォルトテンプレートエンジンです。テンプレート内の特殊な構文マーカーを読み取り、データを変数に置換して最終的なHTMLページを出力します。

基本的な構文

  • コメント: {# コメント #}
  • 式: {{ 式 }}
  • ロジック: {% ロジック %}

条件分岐

{% if 条件 %}
    条件が真の場合のコンテンツ
{% elif other_condition %}
    その他の条件が真の場合のコンテンツ
{% else %}
    条件が偽の場合のコンテンツ
{% endif %}

ループ

{% for item in items %}
    <p>{{ item.name }} - {{ item.price }}円</p>
{% endfor %}

ループ内で利用できる特別な変数:

  • loop.index: ループカウンター(1から)
  • loop.index0: ループカウンター(0から)
  • loop.first: 最初の要素かどうか
  • loop.last: 最後の要素かどうか

テンプレートの例

# Python側
from flask import Flask, render_template

app = Flask(__name__)

PRODUCTS = [
    {"name": "リンゴ", "price": 200, "category": "果物"},
    {"name": "バナナ", "price": 150, "category": "果物"},
    {"name": "パン", "price": 300, "category": "パン"}
]

@app.route("/products")
def products():
    return render_template("products.html", products=PRODUCTS)

# products.htmlテンプレート
<html>
<head>
    <title>商品一覧</title>
</head>
<body>
    <h1>商品一覧</h1>
    
    {% for product in products %}
        <div>
            <h2>{{ product.name }}</h2>
            <p>価格: {{ product.price }}円</p>
            {% if product.category == "果物" %}
                <p>カテゴリ: 果物</p>
            {% else %}
                <p>カテゴリ: その他</p>
            {% endif %}
        </div>
    {% endfor %}
</body>
</html>

まとめ

Flaskのリクエストとレスポンス処理、テンプレートシステムを理解することで、動的なWebアプリケーションを構築できます。Jinja2テンプレートエンジンを活用することで、データ駆動型のページを効率的に生成できます。

タグ: flask Python Web開発 Jinja2 リクエスト

7月22日 01:31 投稿