零基礎學Flask:模板繼承與變量渲染

什麼是Flask模板系統?

在學習Flask時,我們常常需要將動態數據(比如用戶信息、數據庫內容)生成HTML頁面。Flask使用Jinja2模板引擎來完成這個工作,它就像一個”HTML生成器”,讓我們可以在HTML中嵌入Python代碼或變量,實現頁面的動態渲染。

今天我們要掌握兩個核心技能:變量渲染(把Python變量顯示到頁面)和模板繼承(避免重複寫HTML結構),這兩個功能是構建大型Flask應用的基礎。

一、變量渲染:讓頁面”活”起來

變量渲染是指將Python代碼中的變量(比如字符串、列表、字典)顯示到HTML頁面上。Jinja2提供了{{ variable }}語法來實現,非常簡單。

1. 準備工作:安裝Flask並創建項目

首先確保你已經安裝了Flask:

pip install flask

創建一個簡單的項目結構,如下:

my_flask_app/
├── app.py       # Flask主程序
└── templates/   # 存放HTML模板的文件夾
    └── index.html  # 首頁模板

2. 視圖函數傳參:把變量送到模板

app.py中,我們先定義一個視圖函數,用來處理用戶請求並傳遞變量到模板:

from flask import Flask, render_template

app = Flask(__name__)

# 定義首頁路由,視圖函數名爲home
@app.route('/')
def home():
    # 定義幾個不同類型的變量
    username = "小明"          # 字符串
    age = 20                   # 數字
    hobbies = ["籃球", "編程", "看書"]  # 列表
    user_info = {              # 字典
        "height": 175,
        "weight": 65,
        "city": "北京"
    }
    # 渲染index.html模板,並傳遞上述變量
    return render_template('index.html', 
                          username=username, 
                          age=age, 
                          hobbies=hobbies, 
                          info=user_info)

if __name__ == '__main__':
    app.run(debug=True)  # 啓動Flask應用,debug模式方便開發

3. 模板中使用變量:{{ }}語法

templates/index.html中,我們用{{ 變量名 }}來顯示Python變量:

<!DOCTYPE html>
<html>
<head>
    <title>{{ username }}的個人主頁</title>
</head>
<body>
    <h1>歡迎來到我的主頁!</h1>
    <p>我叫{{ username }},今年{{ age }}歲。</p>  <!-- 顯示字符串和數字 -->

    <h2>我的愛好:</h2>
    <ul>
        {% for hobby in hobbies %}  <!-- 循環遍歷列表 -->
            <li>{{ hobby }}</li>
        {% endfor %}
    </ul>

    <h2>詳細信息:</h2>
    <p>身高:{{ info.height }}cm</p>  <!-- 字典通過鍵取值 -->
    <p>居住城市:{{ info.city }}</p>
</body>
</html>

運行效果:訪問http://127.0.0.1:5000/,頁面會顯示:

歡迎來到我的主頁!
我叫小明,今年20歲。

我的愛好:
- 籃球
- 編程
- 看書

詳細信息:
身高:175cm
居住城市:北京

4. 不同類型變量的渲染技巧

除了基礎的字符串和數字,Jinja2還支持複雜類型變量的渲染:

  • 列表循環:用{% for 變量 in 列表 %}遍歷列表(如上例中的hobbies)
  • 字典取值:用{{ 字典.鍵 }}{{ 字典['鍵'] }}(如上例中的info.city)
  • 條件判斷:用{% if 條件 %}控制顯示(比如:{% if age > 18 %}已成年{% else %}未成年{% endif %}

二、模板繼承:讓頁面佈局”複用”

如果多個頁面需要相同的結構(比如導航欄、頁腳),手動複製HTML會很麻煩。模板繼承可以幫我們統一頁面結構,只寫不同的部分。

1. 定義基礎模板(base.html)

創建templates/base.html作爲所有頁面的”骨架”,包含通用部分(導航、頁腳、標題):

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>{% block title %}我的網站{% endblock %}</title>
    <style>
        body { margin: 0; padding: 0; font-family: sans-serif; }
        nav { background: #f5f5f5; padding: 10px; }
        nav a { margin-right: 15px; text-decoration: none; color: #333; }
        .content { padding: 20px; }
        footer { text-align: center; color: #999; padding: 10px; background: #f9f9f9; }
    </style>
</head>
<body>
    <!-- 導航欄(所有頁面通用) -->
    <nav>
        <a href="/">首頁</a>
        <a href="/about">關於</a>
        <a href="/contact">聯繫我們</a>
    </nav>

    <!-- 內容塊:不同頁面會在這裏填自己的內容 -->
    <div class="content">
        {% block content %}{% endblock %}
    </div>

    <!-- 頁腳(所有頁面通用) -->
    <footer>
        © 2023 我的網站 - 模板繼承示例
    </footer>
</body>
</html>

關鍵知識點
- {% block title %}:標題的佔位塊,子模板可以重寫
- {% block content %}:內容的佔位塊,子模板需要填充這裏
- {% extends "base.html" %}:子模板繼承基礎模板(後面會用)

2. 子模板繼承基礎模板

現在創建首頁index.html,繼承base.html並只修改內容塊:

{% extends "base.html" %}  <!-- 繼承基礎模板 -->

{% block title %}首頁 - 我的網站{% endblock %}  <!-- 重寫標題塊 -->

{% block content %}  <!-- 重寫內容塊 -->
    <h1>歡迎來到首頁!</h1>
    <p>這是一個使用模板繼承的示例頁面。</p>
    <p>當前時間:{{ now }}</p>  <!-- 用Python變量顯示時間 -->
{% endblock %}

再創建關於頁about.html,同樣繼承基礎模板:

{% extends "base.html" %}

{% block title %}關於我們 - 我的網站{% endblock %}

{% block content %}
    <h1>關於我們</h1>
    <p>這是一個用Flask製作的簡單網站,主要展示模板繼承和變量渲染。</p>
    <p>我們的目標是幫助零基礎學習者快速掌握Flask開發。</p>
{% endblock %}

3. 讓視圖函數支持子模板

修改app.py,讓首頁和關於頁能調用對應的子模板:

from flask import Flask, render_template
from datetime import datetime  # 新增:獲取當前時間

app = Flask(__name__)

@app.route('/')
def home():
    # 傳遞當前時間到模板
    return render_template('index.html', now=datetime.now().strftime("%Y-%m-%d %H:%M:%S"))

@app.route('/about')
def about():
    return render_template('about.html')  # 直接渲染about.html

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

4. 模板繼承的優勢

  • 代碼複用:導航欄、頁腳等重複部分只寫一次
  • 統一風格:所有頁面保持一致的佈局和樣式
  • 維護方便:修改一個基礎模板,所有子模板自動更新

三、完整示例:變量渲染+模板繼承

把上面的代碼整合後,訪問不同頁面會看到:
- 首頁:繼承base.html,顯示動態時間和歡迎內容
- 關於頁:繼承base.html,顯示關於信息

這種方式讓我們的代碼既簡潔又高效,避免了重複編寫相同的HTML結構。

四、常見問題與解決方法

  1. 模板找不到?
    確保模板文件放在templates文件夾下,且路徑正確(比如render_template('about.html'))。

  2. 變量顯示錯誤?
    檢查變量名是否拼寫錯誤,比如模板中寫{{ usrname }}(少了個r)會顯示空值。

  3. 繼承不生效?
    確認{% extends "base.html" %}寫在子模板最開頭,且基礎模板文件名正確。

總結

今天我們學會了:
- 變量渲染:用{{ 變量 }}在HTML中顯示Python變量,支持列表、字典等
- 模板繼承:通過{% extends %}{% block %}複用頁面結構,統一風格
- 項目結構app.py處理邏輯,templates存放模板文件

這些技能是構建Flask應用的基石,接下來可以嘗試添加更多頁面或連接數據庫,讓你的網站更強大!

(提示:可以在app.py中添加更多路由和變量,比如contact.htmluser.html等,練習模板繼承和變量渲染)

小夜