Flask 教程 第十一章:美化

本文翻译自The Flask Mega-Tutorial Part XI: Facelift

这是Flask Mega-Tutorial系列的第十一部分,我将告诉你如何用基于Bootstrap用户界面框架的新模板替换基础的HTML模板。

你把玩Microblog应用也有一段时间了,所以我相信你已经注意到,我没有花太多时间来美化它,说得更具体点,我根本没有花时间。 所有的模板只使用了基础样式,没有任何自定义的展现。 这对于我来说却非常有用,因为我可以专注于应用的实际逻辑,不用分心于编写好看的HTML和CSS代码。

但是我已经长期关注应用的后端部分一段时间了。 因此在本章中,我暂停一下后端的工作,并花点时间向你展示如何使应用看起来更加优雅和专业。

本章将与之前的章节略有不同,因为我不会像平常解说Python那样,事无巨细,一一道来,毕竟Python才是本教程的主要内容。 创建漂亮的网页是一个很广泛的话题,而与Python Web的后端开发很大程度上无关,因此我将讨论一些基本的指导方针和想法,你可以通过重新设计应用的外观来研究和学习它。

本章的GitHub链接为:BrowseZipDiff.

CSS框架

虽然我们可以争辩说写代码不容易,但是与那些必须让网页在所有Web浏览器上具有良好一致外观的网页设计师相比,我们的痛苦不值一提。 虽然近年来这种情况得到一定程度的缓解,但是在一些浏览器中仍然存在着晦涩的错误或奇怪的设定,这使得设计网页的任务变得非常困难。 如果还需要兼容屏幕限制设备(诸如平板电脑和智能手机)的浏览器,则更加困难。

如果你和我一样,只是一个想创建出规范网页的开发人员,没有时间或兴趣去学习底层机制并通过编写原生HTML和CSS来实现它,那么唯一可行的解决方案是使用CSS框架来简化任务。 通过这种方式,你会失去一些创造性的自由,但另一方面,无需通过太多的功夫就可以让网页在所有浏览器中看起来都不错。 CSS框架为普通类型的用户界面元素提供了高级CSS类的集合,其中包含预定义样式。 大多数这样的框架还提供JavaScript插件,以实现不能纯粹使用HTML和CSS来完成的功能。

Bootstrap简介

最受欢迎的CSS框架之一是由Twitter推出的Bootstrap。 如果你想看看这个框架可以设计的页面类型,文档有一些示例

这些是使用Bootstrap来设置网页风格的一些好处:

  • 在所有主流网页浏览器中都有相似的外观
  • 自动处理PC桌面,平板电脑和手机屏幕尺寸
  • 可定制的布局
  • 精心设计的导航栏,表单,按钮,警示,弹出窗口等

使用Bootstrap最直接的方法是简单地在你的基本模板中导入bootstrap.min.css文件。 可以下载此文件并将其添加到你的项目中,或直接从CDN导入。 然后,你可以根据其文档开始使用它提供的通用CSS类,实在是太棒了。 你可能还需要导入包含框架JavaScript代码的bootstrap.min.js文件,以便使用最先进的功能。

幸运的是,有一个名为Flask-Bootstrap的Flask插件,它提供了一个已准备好的基础模板,该模板引入了Bootstrap框架。 让我们来安装这个扩展:

1 (venv) $ pip install flask-bootstrap

使用Flask-Bootstrap

Flask-Bootstrap需要像大多数其他Flask插件一样被初始化:

app/init.py: Flask-Bootstrap实例。

1 # ...
2 from flask_bootstrap import Bootstrap
3
4 app = Flask(__name__)
5 # ...
6 bootstrap = Bootstrap(app)

在初始化插件之后,bootstrap/base.html模板就会变为可用状态,你可以使用extends子句从应用模板中引用。

但是,回顾一下,我已经使用了extends子句来继承我的基础模板,这使我可以将页面的公共部分放在一个地方。 base.html模板定义了导航栏,其中包含几个链接,并且还导出了一个content块。 应用中的所有其他模板都从基础模板继承,并为内容块提供页面的主要内容。

那么我怎样才能适配Bootstrap基础模板呢? 解决方案是从使用两个层级到使用三个层级。 bootstrap/base.html模板提供页面的基本结构,其中引入了Bootstrap框架文件。 这个模板为派生的模板定义了一些块,例如titlenavbarcontent(参见块的完整列表)。 我将更改base.html模板以从bootstrap/base.html派生,并提供titlenavbarcontent块的实现。 反过来,base.html将为从其派生的模板导出app_content块以定义页面内容。

下面你可以看到从Bootstrap基础模板派生的base.html的代码。 请注意,此列表不包含导航栏的整个HTML,但你可以在GitHub上或下载本章的代码来查看完整的实现。

app/templates/base.html:重新设计后的基础模板。

 1 {% extends ‘bootstrap/base.html‘ %}
 2
 3 {% block title %}
 4     {% if title %}{{ title }} - Microblog{% else %}Welcome to Microblog{% endif %}
 5 {% endblock %}
 6
 7 {% block navbar %}
 8     <nav class="navbar navbar-default">
 9         ... navigation bar here (see complete code on GitHub) ...
10     </nav>
11 {% endblock %}
12
13 {% block content %}
14     <div class="container">
15         {% with messages = get_flashed_messages() %}
16         {% if messages %}
17             {% for message in messages %}
18             <div class="alert alert-info" role="alert">{{ message }}</div>
19             {% endfor %}
20         {% endif %}
21         {% endwith %}
22
23         {# application content needs to be provided in the app_content block #}
24         {% block app_content %}{% endblock %}
25     </div>
26 {% endblock %}

从中你可以看到我如何从bootstrap/base.html派生此模板,接下来分别实现了页面标题、导航栏和页面内容的这三个模块。

title块需要使用<title>标签来定义用于页面标题的文本。 对于这个块我简单地挪用了原始基本模板中<title>标签内部的逻辑。

navbar块是一个可选块,用于定义导航栏。 对于此块,我调整了Bootstrap导航栏文档中的示例,以便它在左侧展示网站品牌,跟着是Home和Explore的链接。 然后我添加了个人主页和登录或注销链接并使其与页面的右边界对齐。 正如我上面提到的,我在上面的例子中省略了HTML,但是你可以从本章的下载包中获得完整的base.html模板。

最后,在content块中,我定义了一个顶级容器,并在其中设定了呈现闪现消息的逻辑,这些消息现在将显示为Bootstrap警示的样式。 接下来是一个新的app_content块,这个块用于从其派生的模板来定义他们自己的内容。

所有页面模板的原始版本在名为content的块中定义了它们的内容。 正如你在上面看到的,Flask-Bootstrap使用名为content的块,所以我将我的内容块重命名为app_content。 所以我所有的模板都必须重命名为使用app_content作为它们的内容块。 例如,这是404.html模板的修改后版本的展示:

app/templates/404.html:重新设计后的404错误模板。

1 {% extends "base.html" %}
2
3 {% block app_content %}
4     <h1>File Not Found</h1>
5     <p><a href="{{ url_for(‘index‘) }}">Back</a></p>
6 {% endblock %}

渲染Bootstrap表单

Flask-Bootstrap在渲染表单这方面做得非常出色。 Flask-Bootstrap不需要逐个设置表单字段,而是使用一个接受Flask-WTF表单对象作为参数的宏,并以Bootstrap样式渲染出完整的表单。

下面你可以看到重新设计后的register.html模板:

app/templates/register.html::用户注册模板。

{% extends "base.html" %}
{% import ‘bootstrap/wtf.html‘ as wtf %}

{% block app_content %}
    <h1>Register</h1>
    <div class="row">
        <div class="col-md-4">
            {{ wtf.quick_form(form) }}
        </div>
    </div>
{% endblock %}

是不是很棒? 顶端附近的import语句与Python导入类似。 这增加了一个wtf.quick_form()宏,它在单行代码中渲染完整的表单,包括对显示验证错误的支持,并且适配Bootstrap框架的所有样式。

再一次地,我不会向你展示我为应用中的其他表单所做的所有更改,但这些更改都是可以在GitHub上下载或检查到的。

渲染用户动态

单条用户动态的渲染逻辑被提取到名为_post.html的子模板中。 我只需要在这个模板上做一些很小的调整,就可以使其在Bootstrap下看起来很棒了。

app/templates/_post.html: 重新设计后的用户动态子模板。

 1     <table class="table table-hover">
 2         <tr>
 3             <td width="70px">
 4                 <a href="{{ url_for(‘user‘, username=post.author.username) }}">
 5                     <img src="{{ post.author.avatar(70) }}" />
 6                 </a>
 7             </td>
 8             <td>
 9                 <a href="{{ url_for(‘user‘, username=post.author.username) }}">
10                     {{ post.author.username }}
11                 </a>
12                 says:
13                 <br>
14                 {{ post.body }}
15             </td>
16         </tr>
17     </table>

渲染分页链接

分页链接是Bootstrap提供直接支持的另一个方面。 为此,我再一次访问Bootstrap 文档,并修改了其中的一个示例。 以下是在index.html页面中的分页链接的代码:

app/templates/index.html: 重新设计后的分页链接。

 1     ...
 2     <nav aria-label="...">
 3         <ul class="pager">
 4             <li class="previous{% if not prev_url %} disabled{% endif %}">
 5                 <a href="{{ prev_url or ‘#‘ }}">
 6                     <span aria-hidden="true">&larr;</span> Newer posts
 7                 </a>
 8             </li>
 9             <li class="next{% if not next_url %} disabled{% endif %}">
10                 <a href="{{ next_url or ‘#‘ }}">
11                     Older posts <span aria-hidden="true">&rarr;</span>
12                 </a>
13             </li>
14         </ul>
15     </nav>

请注意,在分页链接的实现中,当某个方向没有更多内容时,不是隐藏该链接,而是使用禁用状态,这会使该链接显示为灰色。

类似的更改需要应用于user.html,但我不打算展示在此处。 本章的下载包中包含这些更改。

对比

请下载本章的zip文件并更新应用。

下面你可以对照几张美化前后的图片来观察转变情况。 请记住,这种转变是在不改变一行应用逻辑代码的情况下实现的!

原文地址:https://www.cnblogs.com/sunwk/p/12059038.html

时间: 2024-10-12 05:06:56

Flask 教程 第十一章:美化的相关文章

2017.2.15 开涛shiro教程-第二十一章-授予身份与切换身份(一) table、entity、service、dao

原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 第二十一章 授予身份与切换身份(一) 1.使用场景 某个领导因为某些原因不能访问一些网站,他想把这个网站上的工作委托给秘书,但是他又不想提供账户.密码.此时可以使用shiro的 RunAs 功能. RunAs:允许一个用户假装为另一个用户(如果获得了允许)的身份进行访问. 注意,本章代码基于<第十六章 综合实例>,详细的数据模型及基本流程见该章. 2.表及数据

Flask 教程 第四章:数据库

本文翻译自 The Flask Mega-Tutorial Part IV: Database 在Flask Mega-Tutorial系列的第四部分,我将告诉你如何使用数据库. 本章的主题是重中之重!大多数应用都需要持久化存储数据,并高效地执行的增删查改的操作,数据库为此而生. 本章的GitHub链接为: Browse, Zip, Diff. Flask中的数据库 Flask本身不支持数据库,相信你已经听说过了. 正如表单那样,这也是Flask有意为之.对使用的数据库插件自由选择,岂不是比被迫

Flask 教程 第十七章:Linux上的部署

本文翻译自The Flask Mega-Tutorial Part XVII: Deployment on Linux 这是Flask Mega-Tutorial系列的第十七部分,我将把Microblog部署到Linux服务器. 在本章中,我将谈到Microblog应用生命周期中的一个里程碑,因为我将讨论如何将应用部署到生产服务器上,以便真实用户可以访问它. 部署的主题非常广泛,因此不可能在这里涵盖所有范畴. 本章致力于探讨传统托管方式,包括Ubuntu发行版的Linux服务器和流行的树莓派微机

Flask 教程 第五章:用户登录

本文翻译自The Flask Mega-Tutorial Part V: User Logins 这是Flask Mega-Tutorial系列的第五部分,我将告诉你如何创建一个用户登录子系统. 你在第三章中学会了如何创建用户登录表单,在第四章中学会了运用数据库.本章将教你如何结合这两章的主题来创建一个简单的用户登录系统. 本章的GitHub链接为:Browse, Zip, Diff. 密码哈希 在第四章中,用户模型设置了一个password_hash字段,到目前为止还没有被使用到. 这个字段的

C#图解教程 第十一章 枚举

枚举 枚举 设置底层类型和显式值隐式成员编号 位标志 Flags特性使用位标志的示例 关于枚举的补充 枚举 枚举 枚举是由程序员定义的类型与类或结构一样. 与结构一样,枚举是值类型,因此直接存储它们的数据,而不是分开存储成引用和数据 枚举只有一种类型的成员:命名的整数值常量 例:枚举示例 关键字 枚举名称 ↓ ↓ enum TrafficLight { Green, ← 逗号分隔,没有分号 Yellow, Red } 每个枚举类型都有一个底层整数类型,默认为int. 每个枚举成员都被赋予一个底层

D3.js的v5版本入门教程(第十一章)——交互式操作

D3.js的v5版本入门教程(第十一章) 与图形进行交互操作是很重要的!所谓的交互操作也就是为图形元素添加监听事件,比如说当你鼠标放在某个图形元素上面的时候,就会显示相应的文字,而当鼠标移开后,文字就会消失,或者鼠标单击一下某图形元素就会使它动起来 为了与图形元素进行交互操作,我们还是需要以下新的知识点 on("eventName",function):该函数是添加一个监听事件,它的第一个参数是事件类型,第二个参数是响应事件的内容d3.select(this),选择当前元素    常见

《Java并发编程实战》第十一章 性能与可伸缩性 读书笔记

造成开销的操作包括: 1. 线程之间的协调(例如:锁.触发信号以及内存同步等) 2. 增加的上下文切换 3. 线程的创建和销毁 4. 线程的调度 一.对性能的思考 1 性能与可伸缩性 运行速度涉及以下两个指标: 某个指定的任务单元需要"多快"才能处理完成.计算资源一定的情况下,能完成"多少"工作. 可伸缩性: 当增加计算资源时(例如:CPU.内存.存储容器或I/O带宽),程序的吞吐量或者处理能力能相应地增加. 2 评估各种性能权衡因素 避免不成熟的优化.首先使程序正

计算机系统要素:第十一章 编译器:代码生成

一,项目介绍 终于来到了编译器部分的最后一个章节--代码生成阶段.本章的目标就是将Jack语言转化为VM语言,完成Jack编译器的构建. 刚刚接触这章的内容时,会比较难上手,最主要的问题就在于,这章的内容看起来和第十章没有什么关系.刚开始做这个项目时,我就很疑惑,第十章输出的不是一个结构化的xml文件吗?这个文件在第十一章根本不需要输出,那么这章的内容从何开始呢? 的确,这个xml文件是不需要输出的,但是第十章的目的并不单纯是输出这个xml文件,它更重要的目的是为了让我们了解如何对jack程序文

Flask教程 —— Web表单(上)

第二章中介绍的request对象公开了所有客户端发送的请求信息.特别是request.form可以访问POST请求提交的表单数据. 尽管Flask的request对象提供的支持足以处理web表单,但依然有许多任务会变得单调且重复.表单的HTML代码生成和验证提交的表单数据就是两个很好的例子. Flask-WTF扩展使得处理web表单能获得更愉快的体验.该扩展是一个封装了与框架无关的WTForms包的Flask集成. Flask-WTF和它的依赖集可以通过pip来安装: (venv) $ pip