2019独角兽企业重金招聘Python工程师标准>>>

模板

回顾

如果你依照 Hello World 这一章的话,你应当有一个完全工作的简单的 web 应用程序,它有着如下的文件结构:

microblog\
flask\<virtual environment files>
app\static\templates\__init__.pyviews.py
tmp\
run.py

你可以执行 run.py 来运行应用程序,接着在你的网页浏览器上打开 http://localhost:5000 网址。

在 Python 中生成 HTML 并不好玩,实际上是相当繁琐的,因为你必须自行做好 HTML 转义以保持应用程序的安全。由于这个原因,Flask 自动为你配置好 Jinja2 模版。我们将会在这一章中介绍一些模板基本概念以及基本用法。

我们接下来讲述的正是我们上一章离开的地方,所以你可能要确保应用程序 microblog 正确地安装和工作。

为什么我们需要模板

让我们来考虑下我们该如何扩充我们这个小的应用程序。

我们希望我们的微博应用程序的主页上有一个欢迎登录用户的标题,这是这种类型的应用程序的一个“标配”。忽略本应用程序暂未有用户的事实,我会在后面的章节引入用户的概念。

输出一个漂亮的大标题的一个容易的选择就是改变我们的视图功能,输出 HTML,也许像这个样子:

from app import app@app.route('/')
@app.route('/index')
def index():user = { 'nickname': 'Miguel' } # fake userreturn '''
<html><head>    <title>Home Page</title>  </head>  <body>    <h1>Hello, '''+ user['nickname'] + '''</h1>  </body>
</html>'''

运行看看网页浏览器上的显示情况。

我们暂时还不支持用户,所以暂时使用占位符的用户对象,有时也被称为假冒或模仿的对象。这样让我们可以集中关注应用程序的某一方面,而不用花心思在暂未完成的部分上。

我希望你同意我的说法,上面的解决方案是非常难看!如果我们需要返回一个含有大量动态内容的大型以及复杂的 HTML 页面的话,代码将会有多么复杂啊!如果你需要改变你的网站布局,在一个大的应用程序,该应用程序有几十个视图,每一个直接返回HTML?这显然不是一个可扩展的选择。

模板从天而降

如果你能够保持你的应用程序与网页的布局或者界面逻辑上是分开的,这样不是显得更加容易组织?难道你不觉得是这样吗?你甚至可以聘请一个网页设计师来设计一个杀手级的网页而你专注于 Python 编码。模板可以帮助实现这种分离。

让我们编写第一个我们的模板(文件 app/templates/index.html):

<html><head><title>{{title}} - microblog</title></head><body><h1>Hello, {{user.nickname}}!</h1></body>
</html>

正如你在上面看到,我们只是写了一个大部分标准的HTML页面,唯一的区别是有一些动态内容的在 {{ ... }} 中。

现在看看怎样在我们的视图函数(文件 app/views.py)中使用这些模板:

from flask import render_template
from app import app@app.route('/')
@app.route('/index')def index():user = { 'nickname': 'Miguel' } # fake userreturn render_template("index.html",title = 'Home',user = user)

试着运行下应用程序看看模板是如何工作的。一旦在你的网页浏览器上呈现该网页,你可以浏览下 HTML 源代码,与原始的模板内容对比下差别。

为了渲染模板,我们必须从 Flask 框架中导入一个名为 render_template 的新函数。此函数需要传入模板名以及一些模板变量列表,返回一个所有变量被替换的渲染的模板。

在内部,render_template 调用了 Jinja2 模板引擎,Jinja2 模板引擎是 Flask 框架的一部分。Jinja2 会把模板参数提供的相应的值替换了 {{...}} 块。

模板中控制语句

Jinja2 模板同样支持控制语句,像在 {%...%} 块中。让我们在我们的模板中添加一个 if 声明(文件 app/templates/index.html):

<html><head>{% if title %}<title>{{title}} - microblog</title>{% else %}<title>Welcome to microblog</title>{% endif %}</head><body><h1>Hello, {{user.nickname}}!</h1></body>
</html>

现在我们的模板变得更加智能了。如果视图函数忘记输入页面标题的参数,不会触发异常反而会出现我们自己提供的标题。放心地去掉视图函数中 render_template 的调用中的 title 参数,看看 if 语句是如何工作的!

模板中的循环语句

在我们 microblog 应用程序中,登录的用户想要在首页展示他的或者她的联系人列表中用户最近的文章,因此让我们看看如何才能做到。

首先我们先创建一些用户以及他们的文章用来展示(文件 app/views.py):

def index():user = { 'nickname': 'Miguel' } # fake userposts = [ # fake array of posts{'author': { 'nickname': 'John' },'body': 'Beautiful day in Portland!'},{'author': { 'nickname': 'Susan' },'body': 'The Avengers movie was so cool!'}]return render_template("index.html",title = 'Home',user = user,posts = posts)

为了表示用户的文章,我们使用了列表,其中每一个元素包含 author 和 body 字段。当我们使用真正的数据库的时候,我们会保留这些字段的名称,因此我们在设计以及测试模板的时候尽管使用的是假冒的对象,但不必担心迁移到数据库上更新模板。

在模板这一方面,我们必须解决一个新问题。列表中可能有许多元素,多少篇文章被展示将取决于视图函数。模板不会假设有多少文章,因此它必须准备渲染视图传送的文章数量。

因此让我们来看看怎么使用 for 来做到这一点(文件 app/templates/index.html):

<html><head>{% if title %}<title>{{title}} - microblog</title>{% else %}<title>microblog</title>{% endif %}</head><body><h1>Hi, {{user.nickname}}!</h1>{% for post in posts %}<p>{{post.author.nickname}} says: <b>{{post.body}}</b></p>{% endfor %}</body>
</html>

简单吧?试试吧,确保给予足够的文章列表。

模板继承

在这一章结束前我们将讨论最后一个话题。

在我们的 microblog 应用程序中,在页面的顶部需要一个导航栏。在导航栏里面有编辑账号,登出等等的链接。

我们可以在 index.html 模板中添加一个导航栏,但是随着应用的扩展,越来越多的模板需要这个导航栏,我们需要在每一个模板中复制这个导航栏。然而你必须要保证每一个导航栏都要同步,如果你有大量的模板,这需要花费很大的力气。

相反,我们可以利用 Jinja2 的模板继承的特点,这允许我们把所有模板公共的部分移除出页面的布局,接着把它们放在一个基础模板中,所有使用它的模板可以导入该基础模板。

所以让我们定义一个基础模板,该模板包含导航栏以及上面谈论的标题(文件 app/templates/base.html):

<html><head>{% if title %}<title>{{title}} - microblog</title>{% else %}<title>microblog</title>{% endif %}</head><body><div>Microblog: <a href="/index">Home</a></div><hr>{% block content %}{% endblock %}</body>
</html>

在这个模板中,我们使用 block 控制语句来定义派生模板可以插入的地方。块被赋予唯一的名字。

接着现在剩下的就是修改我们的 index.html 模板继承自 base.html (文件 app/templates/index.html):

{% extends "base.html" %}
{% block content %}
<h1>Hi, {{user.nickname}}!</h1>
{% for post in posts %}
<div><p>{{post.author.nickname}} says: <b>{{post.body}}</b></p></div>
{% endfor %}
{% endblock %}

结束语

如果你想要节省时间的话,你可以下载 microblog-0.2.zip。

但是请注意的是 zip 文件已经不包含 flask 虚拟环境了,如果你想要运行应用程序的话,请按照前一章的步骤自己创建它。

在下一章中,我们将会讨论到表单。我希望能在下一章继续见到各位!

转载于:https://my.oschina.net/CandyMi/blog/621997

(二)Flask 学习 —— 模板相关推荐

  1. OpenCV学习(二十三) :模板匹配:matchTemplate(),minMaxLoc()

    OpenCV学习(二十三) :模板匹配:matchTemplate() 1.概述 模板匹配是一种最原始.最基本的模式识别方法,研究某一特定对象物的图案位于图像的什么地方,进而识别对象物,这就是一个匹配 ...

  2. Flask学习之旅——2.1 模板简介及基础使用

    Flask学习之旅--2.1 模板简介及基础使用 前言 本文为<知了传课--模板简介>的学习笔记. 原文地址:第一节:模板简介 - Python框架Flask基础教程 - 知了传课 (zl ...

  3. Flask奇妙探索之旅(二)之模板

    本文参考来源The-Flask-Mega-Tutorial-zh在翻译的基础上加进了个人的部分理解,仅做个人的学习记录之用. 上一节我们使用Flask构建了自己的第一个Web应用,通过在虚拟环境运行f ...

  4. Flask学习之旅——2.6 模板继承

    Flask学习之旅--2.6 模板继承 前言 本文为<知了传课--模版继承>的学习笔记. 原文地址:第八节:模板继承 - Python框架Flask基础教程 - 知了传课 (zlkt.ne ...

  5. Flask学习之旅——2.2 模板过滤器

    Flask学习之旅--2.2 模板过滤器 前言 本文为<知了传课--Jinja2模版过滤器>的学习笔记. 原文地址:第三节:模板过滤器 - Python框架Flask基础教程 - 知了传课 ...

  6. Flask学习之旅——1.3 URL与视图(二)

    Flask学习之旅--1.3 URL与视图(二) 前言 由于本小节内容较多,故分成几篇文章来记录. 本文为<知了传课--URL与视图>的学习笔记. 原文地址:第三节:URL与视图 - Py ...

  7. Flask学习笔记(四): Flask与数据库连接

    Flask学习笔记(四): Flask与数据库连接 前言 前面我们学习了Flask如何构建一个程序的流程,又研究了它的路由如何设定,还对如何获取模板表单数据进行了梳理,值得一提的就是Flask和SQL ...

  8. Flask学习笔记总结(一)

    Flask学习笔记总结(一) 说明:开始在csdn上面记录一些关于自己学习技术的笔记总结. 文章目录 Flask学习笔记总结(一) 前言 一.python的web三大框架 二.flask入门 1.ws ...

  9. ES6(二)——字符串模板、标签模板字符串、函数的默认参数、剩余参数、数组对象的展开语法、数值的表示、Symbol

    一.字符串模板基本使用 在ES6之前,如果我们想要将字符串和一些动态的变量(标识符)拼接到一起,是非常麻烦和丑陋的(ugly). ES6允许我们使用字符串模板来嵌入JS的变量或者表达式来进行拼接: 首 ...

最新文章

  1. Facebook:正变为下一个微信?
  2. gmod的css模块放哪里,webpack打包css报错找不到模块?
  3. 计算机网络PIC和SDV,SRBSDV和RBSDV检测技术的建立
  4. 支持回调处理 php函数,PHP支持回调的函数有哪些?
  5. 年轻10岁简单又易行的妙方
  6. 近10000灵感配色方案专辑作品,够你用好几年了!
  7. springboot13 页面国际化(i18n)
  8. 2017《面向对象程序设计》课程作业五
  9. 4. 实例palybook安装管理flume
  10. python 日期操作【转】
  11. php mpdf 乱码,PHPMPDF中文乱码如何解决
  12. 开发前奏曲之添加Android SDK平台工具
  13. 小米商城php源码安装教程,搭建小米商城 框架div
  14. c 中空格的asc码表_泰格豪雅卡莱拉系列计时码表,车迷心中的永远的“白月光”...
  15. PS中如何简单、快速更换照片的背景色
  16. $.ajax返回报错,请求ajax报错 返回readyState0
  17. lae界面开发工具入门之介绍九--简单逻辑篇
  18. Flutter TextField 去掉下滑线和底部字符数计数
  19. Spire.Doc在Word中插入图片时,自适应宽度设置
  20. s饥荒服务器物品id,饥荒物品代码大全

热门文章

  1. Windows平台下的session0创建进程的问题与解决办法
  2. Hibernate 异常:“@OneToOne or @ManyToOne on XXX references an unknown entity: XXX”
  3. 开发微信小程序 中遇到的坑 及解决方法
  4. Promise--优雅的异步回调解决方案
  5. IOS图像拉伸解决方案
  6. Maven 无法下载依赖包的解决方法---三步dao!!!
  7. 一个由于springboot自动配置所产生的问题的解决
  8. 为什么++ [[]] [+ []] + [+ []]返回字符串“ 10”?
  9. win11如何登陆本地用户 windows11登陆本地用户的步骤方法
  10. 图片放大缩小旋转左移右移镜像倒影android