# Flask从零到精通|第3课:Jinja2模板引擎 + 静态资源(CSS/JS/图片)
>
> 前置:已掌握路由、url_for。之前我们都是直接返回字符串,真实网站页面是HTML,Flask内置Jinja2模板引擎用来渲染网页。
## 📖 本节课目标
1. 理解模板引擎作用,学会使用 `render_template`
2. 模板变量渲染、模板表达式
3. Jinja2 基础语法:`if` 判断、`for` 循环
4. Flask 静态资源目录规范,加载 css/js/image
5. url_for 加载静态文件
6. 模板继承(base基模板,页面复用,重点)
## 3.1 目录结构(必须严格遵守!Flask默认约定)
在你的 `flask-demo` 项目下新建两个文件夹,名字**不能写错**:
```
flask-demo/
├── app.py
├── templates/ # 存放html模板(固定名字templates)
│ └── index.html
└── static/ # 静态资源 css js img(固定名字static)
├── css/
│ └── style.css
└── images/
```
>
> Flask约定:
>
>
> - `templates`:自动识别,放HTML模板
> - `static`:自动识别,放不会变动的静态文件
## 3.2 render_template 渲染模板
需要导入:`from flask import render_template`
### app.py
```
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
# render_template('模板文件名', 变量名=值)
name = "张三"
age = 20
# 将变量传递给html模板
return render_template("index.html", username=name, user_age=age)
if __name__ == '__main__':
app.run(debug=True)
```
### templates/index.html
```
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>模板页面</title>
</head>
<body>
<!-- Jinja2 变量渲染语法 {{ 变量名 }} -->
<h1>欢迎:{{ username }}</h1>
<p>年龄:{{ user_age }}</p>
</body>
</html>
```
访问 `[。 ## 3.3 Jinja2 基础语法 ### ① 变量运算
```
<p>年龄+5:{{ user_age + 5 }}</p>
```
### ② if 判断 `{% if %}`
```
{% if user_age >= 18 %}
<p>成年人</p>
{% else %}
<p>未成年人</p>
{% endif %}
```
### ③ for循环 `{% for %}`
app.py 传一个列表:
```
@app.route('/list')
def article_list():
articles = ["Flask入门", "路由学习", "模板引擎"]
return render_template("list.html", articles=articles)
```
templates/list.html
```
<!DOCTYPE html>
<html>
<body>
<h2>文章列表</h2>
<ul>
{% for item in articles %}
<li>{{ item }}</li>
{% endfor %}
</ul>
</body>
</html>
```
## 3.4 加载静态资源 static 文件
静态文件使用 `url_for('static', filename="文件路径")`
static/css/style.css
```
h1{
color:red;
}
```
在index.html引入css:
```
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
```
>
> 图片同理:`<img src="{{ url_for('static', filename='images/test.jpg') }}">`
## 3.5 模板继承(项目开发高频⭐)
作用:提取公共页面头部、导航栏、底部,避免每个页面重复写HTML。
### 1. templates/base.html 基模板(父模板)
```
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>{% block title %}默认标题{% endblock %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
<div class="nav">
<a href="/">首页</a> | <a href="/list">文章列表</a>
</div>
<!-- 内容块,子页面填充这里 -->
{% block content %}
默认内容
{% endblock %}
</body>
</html>
```
`{% block 名字 %}` 定义可替换区块
### 2. templates/home.html 子模板,继承base.html
```
{% extends "base.html" %}
{% block title %}首页{% endblock %}
{% block content %}
<h1>这是首页内容</h1>
<p>继承了base的导航栏</p>
{% endblock %}
```
### app.py 增加路由
```
@app.route('/home')
def home():
return render_template("home.html")
```
访问 `/home`,页面自动带上导航栏,只替换content区块。
## ✅ 完整app.py汇总
```
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
name = "张三"
age = 20
return render_template("index.html", username=name, user_age=age)
@app.route('/list')
def article_list():
articles = ["Flask入门", "路由学习", "模板引擎"]
return render_template("list.html", articles=articles)
@app.route('/home')
def home():
return render_template("home.html")
if __name__ == '__main__':
app.run(debug=True)
```
## 📝 本节课小结
1. `render_template()` 渲染templates目录下的html页面,传递变量
2. `{{ 变量 }}` 输出变量;`{% %}` 写if、for、block等逻辑
3. 静态文件放在static文件夹,使用 `url_for('static', filename='')`
4. `{% extends "base.html" %}` 模板继承,实现页面复用,大型项目必备
## 🧪 练习任务
1. 创建base.html基模板,包含导航
2. 新建一个页面 `user.html`,继承base,接收url传过来的用户名并展示
3. 添加css样式,修改页面文字颜色
文章回复
0 条公开回复