Flaskテンプレートで条件分岐と反復処理!if、else、forの使い方

はるか
はるか
テンプレートって何?
ふゅか
ふゅか
テンプレートは、ウェブアプリケーションで動的にHTMLを生成するためのファイルよ。

1. テンプレートとは?

テンプレートは、ウェブアプリケーションにおいて動的にHTMLを生成するためのファイルです。テンプレートエンジンを使用することで、サーバーサイドでデータを埋め込んだり、条件分岐やループなどの制御構造を使ってHTMLを生成したりできます。

はるか
はるか
テンプレートの機能は何?
ふゅか
ふゅか
変数の挿入や条件分岐、ループ、テンプレートの継承など、色々あるわ。データのフォーマットや変換も簡単にできるの。

Flaskでは、Jinja2というテンプレートエンジンが使用されており、次のような機能を提供しています。

  1. 変数の挿入:サーバーサイドのデータをHTML内に埋め込むことができます。
  2. 制御構造:if文やforループなどを使用して、動的なHTMLを生成できます。
  3. テンプレートの継承:共通のレイアウトやヘッダー、フッターを再利用できます。
  4. フィルター:データのフォーマットや変換を簡単に行えます。

Flaskはrender_templateを使って、htmlを描画します。

1.1.  Flaskのインストール

まず、Flaskをインストールします。以下のコマンドを使用します。

pip install flask

1.2.  Flaskアプリケーションの作成

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

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

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

1.3. templates/index.html

Flaskでは、HTMLテンプレートをtemplatesディレクトリに配置します。Flaskは自動的にこのディレクトリからテンプレートを探します。templatesディレクトリを作成し、その中にindex.htmlを作成します。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Flask App</title>
</head>
<body>
    <h1>Hello, Flask!</h1>
</body>
</html>

1.4. アプリケーションの実行

app.pyファイルを実行します。

python app.py

1.5. ブラウザでの確認

ブラウザで http://127.0.0.1:5000/ にアクセスすると、index.htmlテンプレートが表示されます。

2. データのテンプレートへの渡し方

Flaskでは、Pythonからテンプレートにデータを渡すことができます。

はるか
はるか
データはどうやって渡すの?
ふゅか
ふゅか
ルートの中で、render_templateの引数として渡せるの。

2.1. app.py

@app.route('/user/<name>')
def user(name):
    return render_template('user.html', name=name)

このコードでは、Flaskアプリケーションを定義し、/user/<name>というURLパターンにマッチするルートを設定しています。URLの一部として渡されたnameをテンプレートに渡して、HTMLを生成します。

2.2. templates/user.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>User Page</title>
</head>
<body>
    <h1>Hello, {{ name }}!</h1>
</body>
</html>

このHTMLテンプレートは、Flaskのrender_template関数を使って渡されたname変数を受け取り、表示します。{{ name }}の部分がPythonコードから渡されたユーザー名に置き換わります。

3. テンプレートの継承

はるか
はるか
テンプレートの継承って何?
ふゅか
ふゅか
共通のレイアウトを使い回せるのよ。基本のテンプレートに共通部分を書いて、子テンプレートで特定の部分だけ上書きするの。

Flaskでは、テンプレートの継承を利用してHTMLコードを再利用できます。これは、特に大規模なアプリケーションでコードの重複を減らし、メンテナンスを容易にするのに役立ちます。

3.1. templates/base.html

まず、基本的なレイアウトを定義するテンプレートを作成します。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}Flask App{% endblock %}</title>
</head>
<body>
    {% block content %}
    {% endblock %}
</body>
</html>

ここでは、{% block title %}{% block content %} のブロックを定義しています。これらのブロックは、子テンプレートで内容を上書きするために使用されます。

3.2. templates/child.html

次に、共通レイアウトを継承し、特定のページごとの内容を定義する子テンプレートを作成します。

{% extends 'base.html' %}

{% block title %}Child Page{% endblock %}

{% block content %}
    <h1>This is the child page</h1>
{% endblock %}

{% extends 'base.html' %} を使用して、base.html を継承しています。そして、{% block title %}{% block content %} のブロックを上書きして、子テンプレート独自のタイトルと内容を定義しています。

3.3. app.py

@app.route('/child')
def child():
    return render_template('child.html')

これにより、共通のレイアウト(base.html)を利用しつつ、特定のページごとの内容(child.html)を記述することができます。

4. 制御構文if, elif, else の使い方

if文を使うことで、条件に基づいて異なるHTMLを表示することができます。条件に基づいて異なるメッセージを表示する例を示します。

はるか
はるか
条件分岐はどうやって書くの?
ふゅか
ふゅか
{% if %}{% elif %}{% else %}を使うのよ。例えば、スコアに応じて成績を表示する場合、こう書くの。

4.1. if, elif, else の使用

score変数の値に基づいて異なる成績を表示します。{% if %}{% elif %}{% else %}、および{% endif %}を使用して条件分岐を行います。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Condition Example</title>
</head>
<body>
    {% if score >= 90 %}
        <h1>Grade: A</h1>
    {% elif score >= 80 %}
        <h1>Grade: B</h1>
    {% elif score >= 70 %}
        <h1>Grade: C</h1>
    {% else %}
        <h1>Grade: F</h1>
    {% endif %}
</body>
</html>

4.2. app.py

@app.route('/grade/')
def grade(score):
    return render_template('grade.html', score=score)

ブラウザで http://127.0.0.1:5000/grade/85 にアクセスすると、「Grade: B」と表示されます。

5. for の使い方

forループを使うことで、リストや辞書などのデータ構造を反復処理してHTMLを生成することができます。

はるか
はるか
ループは?
ふゅか
ふゅか
{% for item in items %}を使って、リストの各アイテムを表示するの。簡単に繰り返し処理ができるのよ。

5.1. for ループの使用

テンプレート内でのforループを使って、リスト内のアイテムを順に表示する例を示します。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Loop Example</title>
</head>
<body>
    <ul>
        {% for item in items %}
            <li>{{ item }}</li>
        {% endfor %}
    </ul>
</body>
</html>

このテンプレートでは、itemsというリストを{% for item in items %}{% endfor %}で囲んで反復処理しています。各アイテムは<li>{{ item }}</li>としてリスト要素に表示されます。

5.2. app.py

@app.route('/items')
def items():
    items_list = ['Python', 'C', 'C#', 'C++']
    return render_template('loop.html', items=items_list)

ブラウザで http://127.0.0.1:5000/items にアクセスすると、以下のリストが表示されます。items_listというリストをテンプレートに渡して表示します。

6. if と for の組み合わせ

if文とforループを組み合わせることで、さらに複雑なロジックを実装できます。

はるか
はるか
ifとforを組み合わせることはできる?
ふゅか
ふゅか
もちろんできるわ!リストの各アイテムに条件を付けて表示する場合、if文とforループを組み合わせて使うの。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Combined Example</title>
</head>
<body>
    <ul>
        {% for item in items %}
            {% if item.startswith('C') %}
                <li>{{ item }} starts with C</li>
            {% else %}
                <li>{{ item }}</li>
            {% endif %}
        {% endfor %}
    </ul>
</body>
</html>

このテンプレートでは、itemsというリストを{% for item in items %}{% endfor %}で反復処理しています。各アイテムについて、item'C'で始まる場合には「{{ item }} starts with C」という形式で表示し、それ以外の場合には単に「{{ item }}」として表示します。

6.1. app.py

@app.route('/combined')
def combined():
    items_list = ['Python', 'C', 'C#', 'C++']
    return render_template('combined.html', items=items_list)

ブラウザで http://127.0.0.1:5000/combined にアクセスすると、以下のリストが表示されます。

PR