Flask(四) 模板渲染render_template

文章目录

  • 过程详解(路由 <-> HTML 模板)
    • 数据是怎么传过去的?
    • 多变量示例
  • ✅ Jinja2 支持条件判断、循环、模板继承:
  • ✅ 安全性
    • Flask 默认也会对变量进行 HTML 转义:
    • {{ chart | safe }}
      • 在 pyecharts 中怎么用?
  • 模板继承
    • 文件结构示例
      • base.html(母板模板)
      • index.html(子模板)
      • login.html(子模板)
  • 过滤器
  • 宏和模板包含
  • Flask-Login 登录系统
    • 1、安装 Flask-Login:
    • 2、初始化 LoginManager
    • 3、用户模型实现:
    • 4、登录与登出视图示例:
    • 5、当前登录的用户
      • 含义解释
    • 其他常用方法

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

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

过程详解(路由 <-> HTML 模板)

浏览器请求:GET /hello
        ↓
Flask 匹配 @app.route('/hello') → 调用 hello() 函数
        ↓
hello() 中使用 render_template() 渲染 hello.html
        ↓
将 name="张三" 传入模板引擎 Jinja2
        ↓
Jinja2 渲染出 HTML: <h1>你好, 张三!</h1>
        ↓
Flask 把 HTML 打包成 Response 对象返回浏览器
        ↓
浏览器显示页面

数据是怎么传过去的?

render_template("模板名.html", 变量名1=1, 变量名2=2, ...)

模板中用 {{ 变量名 }} 就能访问到。

多变量示例

@app.route('/dashboard')
def dashboard():
    stats = {"pv": 1000, "uv": 300}
    return render_template('dashboard.html', stats=stats, username="admin")

templates/dashboard.html

<h2>欢迎, {{ username }}h2>
<p>页面浏览量:{{ stats.pv }}p>
<p>独立访客数:{{ stats.uv }}p>

✅ Jinja2 支持条件判断、循环、模板继承:

{% if user %}
    <p>欢迎 {{ user }}!p>
{% else %}
    <p>请先登录p>
{% endif %}

{% if user %}:检查 user 变量是否存在,如果存在,则显示欢迎消息,否则显示登录提示。

循环语句:

<ul>
{% for item in items %}
    <li>{{ item }}li>
{% endfor %}
ul>

{% for item in items %}:遍历 items 列表,并为每个项生成一个

  • 元素。

    ✅ 安全性

    自动转义:Jinja2 默认会对模板中的变量进行自动转义,防止 XSS 攻击。
    {{ user_input }}:用户输入的内容会被自动转义,以避免恶意脚本的注入。

    Flask 默认也会对变量进行 HTML 转义:

    比如

    chart = "<script>alert('Hi')script>"
    

    在模版中写

    {{ chart }}
    

    浏览器会看到:

    <script>alert('Hi')</script>
    

    因为 Flask 模板会自动进行 HTML 安全转义。

    {{ chart | safe }}

    {{ chart | safe }} 是 Flask 模板中一个非常常见的写法,特别用于像 pyecharts、plotly 等图表库,把图表插入 HTML 页面的关键语句。
    {{ chart | safe }} 意思是把 chart 的内容作为 HTML 原样输出(不再自动转义)

    在 pyecharts 中怎么用?

    pyecharts 生成的图表是一个 HTML

    from pyecharts.charts import Bar
    from pyecharts import options as opts
    
    bar = (
        Bar()
        .add_xaxis(["A", "B", "C"])
        .add_yaxis("销量", [10, 20, 30])
    )
    chart = bar.render_embed()
    

    在 Flask 中渲染:

    return render_template("chart.html", chart=chart)
    

    模板中这样写:

    <div>
        {{ chart | safe }}
    div>
    

    这样图表就会在页面中正常显示!

    请不要对用户输入的数据使用 | safe,除非你已经对内容做过严格校验,否则可能产生 XSS 攻击漏洞。

    模板继承

    模板继承允许你创建一个基础模板,然后在其他模板中继承和扩展这个基础模板,避免重复的 HTML 代码。

    创建基础模板:在 templates 文件夹中创建一个基础模板 base.html。

    templates/base.html 示例:

    DOCTYPE html>
    <html>
    <head>
        <title>{% block title %}My Website{% endblock %}title>
    head>
    <body>
        <header>
            <h1>My Websiteh1>
        header>
        <main>
            {% block content %}{% endblock %}
        main>
        <footer>
            <p>Footer contentp>
        footer>
    body>
    html>
    

    {% block title %} {% endblock %} {% block content %} {% endblock %} 是定义的可替换区域。
    创建子模板:在 templates 文件夹中创建一个子模板 index.html,继承 base.html。

    templates/index.html 文件代码:

    {% extends "base.html" %}
    
    {% block title %}Home Page{% endblock %}
    
    {% block content %}
    <h2>Welcome to the Home Page!h2>
    <p>Content goes here.p>
    {% endblock %}
    

    {% extends "base.html" %}:继承基础模板。

    {% block title %} {% block content %}:重写基础模板中的块内容。

    文件结构示例

    templates/
    ├── base.html        ← 通用母版模板
    ├── index.html       ← 首页(继承 base)
    └── login.html       ← 登录页(继承 base

    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='style.css') }}">
    head>
    <body>
        <header>
            <h1>我的网站h1>
            <nav>
                <a href="{{ url_for('index') }}">首页a> |
                <a href="{{ url_for('login') }}">登录a>
            nav>
        header>
        
        <main>
            {% block content %}{% endblock %}
        main>
        
        <footer>
            <p>版权所有 © 2025p>
        footer>
    body>
    html>
    
    

    index.html(子模板)

    {% extends "base.html" %}
    
    {% block title %}首页{% endblock %}
    
    {% block content %}
    <h2>欢迎访问首页h2>
    <p>这里是首页内容p>
    {% endblock %}
    
    

    login.html(子模板)

    {% extends "base.html" %}
    
    {% block title %}登录{% endblock %}
    
    {% block content %}
    <h2>登录页面h2>
    <form method="post">
        用户名: <input name="username"><br>
        密码: <input name="password" type="password"><br>
        <button type="submit">登录button>
    form>
    {% endblock %}
    
    

    过滤器

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

    <p>{{ name|capitalize }}p>
    <p>{{ price|round(2) }}p>
    

    {{ name|capitalize }}:将 name 变量的值首字母大写。
    {{ price|round(2) }}:将 price 变量的值四舍五入到小数点后两位。

    宏和模板包含

    宏是可重用的模板片段。模板包含允许你在一个模板中插入另一个模板的内容。
    创建宏

    templates/macros.html 代码文件:
    实例
    {% macro render_item(item) %}
        <div>
            <h3>{{ item.title }}h3>
            <p>{{ item.description }}p>
        div>
    {% endmacro %}
    

    使用宏:

    templates/index.html 文件代码:
    实例

    {% from "macros.html" import render_item %}
    
    <h1>Itemsh1>
    {% for item in items %}
        {{ render_item(item) }}
    {% endfor %}
    

    {% from "macros.html" import render_item %}:导入宏。
    {{ render_item(item) }}:调用宏来渲染每个 item。

    Flask-Login 登录系统

    1、安装 Flask-Login:

    pip install flask-login
    

    2、初始化 LoginManager

    from flask_login import LoginManager
    
    login_manager = LoginManager()
    login_manager.init_app(app)
    
    @login_manager.user_loader
    def load_user(user_id):
        return User.query.get(user_id)
    

    3、用户模型实现:

    from flask_login import UserMixin
    
    class User(db.Model, UserMixin):
        id = db.Column(db.Integer, primary_key=True)
        username = db.Column(db.String(64), unique=True, nullable=False)
        # 其他字段...
    

    UserMixin 提供 is_authenticated、is_active、get_id() 等属性
    UserMixin 添加到你的用户模型中后,它会自动为你提供实现 Flask-Login 所要求的接口。

    4、登录与登出视图示例:

    from flask_login import login_user, logout_user
    
    @app.route('/login', methods=['GET', 'POST'])
    def login():
        user = User.query.filter_by(username="admin").first()
        login_user(user)  # 登录
        return redirect(url_for('index'))
    
    @app.route('/logout')
    def logout():
        logout_user()
        return redirect(url_for('index'))
    

    5、当前登录的用户

    from flask_login import current_user
    
    <body>
      {% if current_user.is_authenticated %}
        <p>欢迎,{{ current_user.username }}!p>
        <a href="{{ url_for('logout') }}">登出a>
      {% else %}
        <p>您尚未登录。p>
        <a href="{{ url_for('login') }}">登录a>
      {% endif %}
    body>
    

    含义解释

    {% if current_user.is_authenticated %}:在使用 Flask-Login 时,current_user 是 Flask 提供的一个全局代理对象,代表当前登录的用户。
    current_user.is_authenticated 是一个布尔值:

    • True:用户已登录
    • False:用户未登录(匿名)

    其他常用方法

    代码 说明
    current_user.is_authenticated 判断当前用户是否登录
    current_user.username 访问当前登录用户属性
    UserMixin 提供用户模型默认认证属性
  • 你可能感兴趣的:(Flask,flask,python,后端)