零基础学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等,练习模板继承和变量渲染)

小夜