当前位置: 首页 > article >正文

【11天从零基础入门flask】第 6 章:模板优化


第 6 章:模板优化

在本章中,我们将学习如何优化 Flask 应用中的模板,解决重复代码问题,使得模板更加清晰、易于维护,并提高开发效率。

6.1 自定义错误页面

Flask 提供了默认的错误页面,例如 404 错误(页面未找到)。但这些默认的错误页面非常简陋,不能提供用户友好的体验。在实际开发中,我们通常需要根据需求自定义错误页面。

1. 编写 404 错误页面模板

首先,我们可以为应用编写一个自定义的 404 错误页面。假设用户访问一个不存在的 URL(例如 /hello),Flask 默认会返回一个简单的 404 错误页面,我们可以通过自定义模板来使页面更加友好。

templates 文件夹中创建一个 404.html 文件,内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>{{ user.name }}'s Watchlist</title>
    <link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}">
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}" type="text/css">
</head>
<body>
    <h2>
        <img alt="Avatar" class="avatar" src="{{ url_for('static', filename='images/avatar.png') }}">
        {{ user.name }}'s Watchlist
    </h2>
    <ul class="movie-list">
        <li>
            Page Not Found - 404
            <span class="float-right">
                <a href="{{ url_for('index') }}">Go Back</a>
            </span>
        </li>
    </ul>
    <footer>
        <small>&copy; 2018 <a href="http://helloflask.com/book/3">HelloFlask</a></small>
    </footer>
</body>
</html>
2. 注册错误处理函数

使用 @app.errorhandler 装饰器来注册一个错误处理函数。当发生 404 错误时,这个函数会被触发,返回自定义的错误页面。

@app.errorhandler(404)
def page_not_found(e):
    user = User.query.first()
    return render_template('404.html', user=user), 404

通过 render_template('404.html', user=user),我们将 user 变量传递给模板,使得页面可以显示用户信息。

现在,当用户访问一个不存在的 URL 时,Flask 会显示我们自定义的错误页面。


6.2 模板上下文处理函数

重复代码是开发中常见的挑战,尤其是像 user 这样的全局变量,需要在多个模板中使用。在 Flask 中,可以使用 上下文处理函数 来自动注入这些变量到每个模板中,避免在每个视图函数中重复传递相同的变量。

1. 创建上下文处理函数

我们使用 @app.context_processor 装饰器注册一个模板上下文处理函数,该函数返回一个字典,字典中的键值对将被自动传递到每个模板中。

@app.context_processor
def inject_user():
    user = User.query.first()
    return dict(user=user)

通过这种方式,我们无需在每个视图函数中传递 user 变量,它会自动注入到每个模板中。

2. 修改视图函数

现在,我们可以删除视图函数中的 user 变量,Flask 会自动将 user 变量注入到模板中:

@app.errorhandler(404)
def page_not_found(e):
    return render_template('404.html'), 404

@app.route('/')
def index():
    movies = Movie.query.all()
    return render_template('index.html', movies=movies)

这简化了代码,减少了重复工作。


6.3 使用模板继承组织模板

Flask 使用 Jinja2 作为模板引擎,它提供了 模板继承 机制,使得我们能够创建一个通用的基模板,在子模板中重用代码,从而避免重复的 HTML 结构。

1. 创建基模板

基模板通常包含应用的公共部分,如导航栏、页脚和页面头部。我们将在 templates 文件夹中创建一个 base.html 文件。

<!DOCTYPE html>
<html lang="en">
<head>
    {% block head %}
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ user.name }}'s Watchlist</title>
    <link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}">
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}" type="text/css">
    {% endblock %}
</head>
<body>
    <h2>
        <img alt="Avatar" class="avatar" src="{{ url_for('static', filename='images/avatar.png') }}">
        {{ user.name }}'s Watchlist
    </h2>
    <nav>
        <ul>
            <li><a href="{{ url_for('index') }}">Home</a></li>
        </ul>
    </nav>
    {% block content %}{% endblock %}
    <footer>
        <small>&copy; 2018 <a href="http://helloflask.com/book/3">HelloFlask</a></small>
    </footer>
</body>
</html>

base.html 中,我们定义了 headcontent 块,这些块将在子模板中被覆盖或填充。

2. 创建子模板

子模板将继承 base.html,并覆盖 content 块以插入特定内容。我们将 index.html 模板修改为:

{% extends 'base.html' %}

{% block content %}
<p>{{ movies|length }} Titles</p>
<ul class="movie-list">
    {% for movie in movies %}
    <li>{{ movie.title }} - {{ movie.year }}
        <span class="float-right">
            <a class="imdb" href="https://www.imdb.com/find?q={{ movie.title }}" target="_blank" title="Find this movie on IMDb">IMDb</a>
        </span>
    </li>
    {% endfor %}
</ul>
<img alt="Walking Totoro" class="totoro" src="{{ url_for('static', filename='images/totoro.gif') }}" title="to~to~ro~">
{% endblock %}

通过 {% extends 'base.html' %},子模板继承了基模板的结构,并在 content 块中插入电影列表。

3. 404 错误页面模板

错误页面也可以使用继承来减少重复代码。例如,我们将 404.html 修改为:

{% extends 'base.html' %}

{% block content %}
<ul class="movie-list">
    <li>
        Page Not Found - 404
        <span class="float-right">
            <a href="{{ url_for('index') }}">Go Back</a>
        </span>
    </li>
</ul>
{% endblock %}

通过模板继承,我们避免了在每个页面中重复编写头部、导航栏和页脚的 HTML 代码。


6.4 添加 IMDb 链接

为了进一步优化我们的页面,我们为每个电影条目添加了一个 IMDb 链接,允许用户快速查看电影的详细信息。

<span class="float-right">
    <a class="imdb" href="https://www.imdb.com/find?q={{ movie.title }}" target="_blank" title="Find this movie on IMDb">IMDb</a>
</span>

CSS 样式如下:

.float-right {
    float: right;
}

.imdb {
    font-size: 12px;
    font-weight: bold;
    color: black;
    text-decoration: none;
    background: #F5C518;
    border-radius: 5px;
    padding: 3px 5px;
}

通过这些优化,我们的主页更加美观且功能丰富。


6.5 本章小结

在本章中,我们学习了如何优化 Flask 模板,解决重复代码的问题。通过自定义错误页面、使用模板上下文处理函数、模板继承等技巧,我们使得模板更加清晰和易于维护。这样做不仅提高了开发效率,也让代码更加简洁。


进阶提示

  1. 错误页面的进一步优化:除了 404 错误页面,你还可以为 400 和 500 错误创建自定义页面,这样可以为用户提供更好的错误处理体验。

  2. 模板优化技巧:通过模板继承和上下文处理函数,可以减少重复代码和提高模板的可复用性。对于复杂的应用,确保模板的组织结构清晰合理。

  3. 动态链接:在实际项目中,IMDB 链接可能需要更复杂的查询,支持多个数据源(如豆瓣、时光网等)。你可以根据需求动态生成这些链接,增强用户体验。

通过本章的学习,你已经掌握了 Flask 模板优化的技巧,下一章将介绍如何处理用户表单输入,进一步完善应用的功能。


http://www.kler.cn/a/538242.html

相关文章:

  • 使用 POI-TL 和 JFreeChart 动态生成 Word 报告
  • 在 Open WebUI+Ollama 上运行 DeepSeek-R1-70B 实现调用
  • Render上后端部署Springboot + 前端Vue 问题及解决方案汇总
  • 基于python多线程多进程爬虫的maa作业站技能使用分析
  • java基础语法中阶
  • 2025-2-10 deepseek本地部署与本地训练最简版本
  • 个人职业发展——效率为王:AI赋能前端开发
  • C语言简单练习题
  • 我的年度写作计划
  • 机器学习中常用的数据预处理方法
  • 深入解析AI技术原理
  • docker环境下部署face-search开源人脸识别模型
  • 我使用deepseek高效学习-分析外文网站Cron定时执行任务
  • 【GeeRPC】Day3:服务注册(Service Register)
  • 开源机器人+具身智能 解决方案+AI
  • 51单片机之引脚图(详解)
  • Redis 集群原理、主从复制和哨兵模式的详细讲解
  • 什么是DDOS网络攻击?
  • Python教程:使用Matplotlib模块画柱状图、饼形图、直方图
  • 【C语言标准库函数】双曲函数:sinh(), cosh(), tanh()
  • 解决基于FastAPI Swagger UI的文档打不开的问题
  • mysql 存储过程和自定义函数 详解
  • 2025年软件测试五大趋势:AI、API安全、云测试等前沿实践
  • (免费送源码)计算机毕业设计原创定制:C#+Asp.Net+SQL Server C#(asp.net)大学生创新创业项目管理系统
  • yolo11训练模型与测试
  • CNN-day8-经典神经网络GoogleNet