Flask学习笔记 - 模板渲染

Flask 模板渲染

模板是包含占位符的 HTML 文件

Flask 使用 Jinja2 模板引擎来处理模板渲染。模板渲染允许你将动态内容插入到 HTML 页面中,使得应用能够生成动态的网页内容。

  1. 创建模板:将 HTML 文件放在 templates 文件夹中,使用 Jinja2 占位符。
  2. 渲染模板:使用 render_template 函数在视图函数中渲染模板。
  3. 模板继承:创建基础模板,允许其他模板继承和扩展。
  4. 控制结构:使用条件语句和循环在模板中控制逻辑。
  5. 过滤器:使用过滤器格式化变量数据。
  6. 宏和模板包含:创建和使用宏以及模板包含,提高模板的复用性。
  7. 安全性:Jinja2 默认对模板变量进行自动转义以防止 XSS 攻击。
  8. 模板上下文:将数据传递给模板,并在模板中使用这些数据。

基本概念/创建模板

模板是包含占位符的 HTML 文件。

Flask 使用 Jinja2 模板引擎来渲染这些模板,将 Python 数据插入到 HTML 中,从而生成最终的网页。

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>Welcome</title>
</head>
<body>
    <h1>{{ title }}</h1>
    <p>Hello, {{ name }}!</p>
</body>
</html>

app.py

python 复制代码
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
    return render_template('index.html',title='Home',name='Misha')

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

格式: {{ 变量名 }}

模板继承

root.html

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}My Website{% endblock %}</title>
</head>
<body>
    <header>
        <h1>My Website</h1>
    </header>
    <main>
        {% block content %}{% endblock %}
    </main>
    <footer>
        <p>Footer content</p>
    </footer>
</body>
</html>

leaf.html

html 复制代码
{% extends "root.html" %}

{% block title %}Home Page{% endblock %}

{% block content %}
<h2>Welcome to the Home Page!</h2>
<p>Content goes here.</p>
{% endblock %}

app.py

python 复制代码
@app.route('/leaf')
def leaf():
    return render_template('leaf.html')

检查响应的内容确实被替换了

格式:可替换区域 {% block 变量名 %} {% endblock %}

控制结构

Jinja2 提供了多种控制结构,用于在模板中实现条件逻辑和循环。

ctrl_flow.html

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>Welcome</title>
</head>
<body>
    <!-- 条件语句 -->
    {% if user %}
    <p>Welcome, {{ user }}!</p>
    {% else %}
    <p>Please log in.</p>
    {% endif %}
    
    <!-- 循环语句 -->
    <ul>
        {% for item in items %}
        <li>{{ item }}</li>
        {% endfor %}
    </ul>
</body>
</html>

app.py

python 复制代码
@app.route('/ctrl_flow')
def ctrl_flow():
    # return render_template('ctrl_flow.html',user="Zhangsan")
    # return render_template('ctrl_flow.html')
    return render_template('ctrl_flow.html',user="Zhangsan",items=['apple','banana','orange'])

传了user

未传user和items

传了user和items

过滤器

过滤器用于在模板中格式化和处理变量数据。

filter.html

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>Welcome</title>
</head>
<body>
<p>{{ name|capitalize }}</p>
<p>{{ price|round(2) }}</p>
</body>
</html>

app.py

python 复制代码
@app.route('/filter')
def filter():
    return render_template('filter.html',name='wangwu',price=2.999)

过滤器的写法与shell中的管道一样都是用"|"来表示

格式: {{ 变量名|处理方法 }}

宏和模板包含

macros.html

html 复制代码
{% macro render_item(item) %}
    <div>
        <h3>{{ item.title }}</h3>
        <p>{{ item.description }}</p>
    </div>
{% endmacro %}

使用宏: macros_demo.html

html 复制代码
{% from "macros.html" import render_item %}

<h1>Items</h1>
{% for item in items %}
    {{ render_item(item) }}
{% endfor %}

app.py

python 复制代码
@app.route('/macros')
def macros():
    # return render_template('macros_demo.html',items=['apple','banana','orange'])
    return render_template('macros_demo.html',items=[{"title":"apple","description":"苹果"},{"title":"banana","description":"香蕉"},{"title":"orange","description":"橘子"}])

变量不正确时的效果

正常的显示

安全性

security.html

html 复制代码
<html>
<head> security </head>
<body>
<p>{{ user_input }}</p>
</body>
</html>
python 复制代码
@app.route('/xss')
def xss():
    return render_template('security.html',user_input='<script> alert(1) </script>')

自动转义:Jinja2 默认会对模板中的变量进行自动转义,防止 XSS 攻击。

<script>标签不会被认为是html元素

模板上下文

视图函数中传递的变量成为模板的上下文,这些变量可以在模板中直接使用。

profile.html

html 复制代码
<h1>{{ user.name }}</h1>
<p>Age: {{ user.age }}</p>

app.py

python 复制代码
@app.route('/profile/<username>')
def profile(username):
    user = {'name': username, 'age': 25}
    return render_template('profile.html', user=user)

参考

  1. Flask模板渲染
相关推荐
AI大模型-小华39 分钟前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子3 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅3 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni3 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学5 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端
赵庆明老师5 小时前
Vben精讲:21-详解web-antd:tsconfig.json
前端·json·vim
wc885 小时前
微软EDGE浏览器功能学习
前端·学习·edge
Csvn6 小时前
🎯 原生 `<dialog>` 元素:终于可以扔掉一半的自定义弹窗组件了?
前端
Csvn6 小时前
🎨 CSS @layer:用「层叠优先级」终结样式打架的世纪难题
前端