Flask开发系列之模板

本文对《FlaskWeb开发:基于python的Web应用开发实战》模板一节做的总结。

Jinja2模板引擎

模板

模板是一个包含响应文本的文件,其中包含用占位变量表示的动态部分,其具体值只在请求的上下文中才能知道。使用真实值替代变量,再返回最终得到的响应字符串,这一过程成为渲染。

Jinja2模板引擎

官网地址

Jinja2是纯python编写的模板引擎,它和Django类似提供non-XML语法,除此之外还支持内联表达式和一个可选的沙箱环境。Jinja2遵守BSD开源协议。

Flask渲染模板使用的是Jinja2模板引擎,所以需要安装Jinja2,pip install Jinja2。

渲染模板

from flask import Flask,render_template

app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html') @app.route('/user/<name>', methods=['GET'])
def reponse(name):
print(name)
return render_template('user.html', name=name) if __name__ == '__main__':
app.run(debug=True)
# Flask提供的render_template函数把Jinja2模板引擎集成到了程序中。
# render_template函数的第一个参数是模板的文件名。
# 随后的参数都是键值对,表示模板中变量对应的真实值。

变量

模板中使用的{{ name }}结构表示一个变量,它是一种特殊的占位符,告诉模块引擎这个位置的值从渲染模板时使用的数据中获取。

Jinja2 能识别所有类型的变量,甚至是一些复杂的类型,例如列表、字典和对象。示例:

<p>A value from a dictionary:{{ mydict['key']}}.</p>
<p>A value from a list:{{ mylist[3]}}.</p>
<p>A value from a list,with a variable index:{{ mylist[myintvar] }}.</p>
<p>A value from an object's method: {{ myobj.somemethod() }}.</p>

Jinja2变量过滤器

过滤器名添加在变量之后,中间使用竖线分隔。
hello, {{ name|capitalize }}

完整过滤器列表

常用过滤器

过滤器名 说明
safe 渲染值时不转义
capitalize 把值得首字母转换成大写,其他字母转换成小写
lower 把值转换成小写形式
upper 把值转换成大写形式
title 把值中每个单词的首字母都换成大写
trim 把值的首位空格去掉
striptags 渲染之前把值中所有的HTML标签都删掉

控制结构

条件控制结构

{% if user %}
Hello,{{ user }}!
{% else %}
Hello, Stranger!
{% endif %}

渲染一组元素

<ul>
{% for comment in comments %}
<li>{{ comment }}</li>
{% endfor %}
</ul>

{{% macro render_comment(comment)%}}
<li>{{ comment }}</li>
{{ endmacro }} <ul>
{% for comment in comments %}
{{ render_comment(comment) }}
{% endfor %}
</ul> 为了重复使用宏,保存在单独文件中,再在需要的模板中导入。
{% import 'macro.html' as macros %}
<ul>
{% for comment in comments%}
{{ macros.render_comment(comment)}}
{% endfor%}
</ul>

复用代码片段

{% include 'common.html' %}

模板继承

- 建一个名为base.html的基模板
<html>
<head>
{% block head %}
<title>{% block title %}{% endblock %} - My Application</title>
{% endblock %}
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html> - 衍生模板中修改block标签定义的元素
{% extends "base.html" %} #定义基模板
{% block title%}Index{% endblock %} #修改title块内容
{% block head %} #修改head块内容
{{ super() }} #原来head中有内容,用super()获取原来的内容
<style>
</style>
{% endblock %}
{% block body %} #修改body块内容
<h1>Hello, World!</h1>
{% endblock %}

使用Flask-Bootstrap集成Twitter Bootstrap

Bootstrap(http://getbootstrap.com/)是 Twitter 开发的一个开源框架,它提供的用户界面组
件可用于创建整洁且具有吸引力的网页,而且这些网页还能兼容所有现代 Web 浏览器。
Bootstrap 是客户端框架,因此不会直接涉及服务器。服务器需要做的只是提供引用了
Bootstrap 层 叠 样 式 表(CSS) 和 JavaScript 文 件 的 HTML 响 应, 并 在 HTML、CSS 和
JavaScript 代码中实例化所需组件。这些操作最理想的执行场所就是模板。
要想在程序中集成 Bootstrap,显然要对模板做所有必要的改动。不过,更简单的方法是
使用一个名为 Flask-Bootstrap 的 Flask 扩展,简化集成的过程。Flask-Bootstrap 使用 pip
安装:
(venv) $ pip install flask-bootstrap

Flask 扩展一般都在创建程序实例时初始化

1. 下载flask-bootstrap

1
pip install flask-bootstrap

2. 找到base.html文件

将site-packages\flask_bootstrap\templates文件夹下的bootstrap目录copy到你的项目\templates目录下,确保bootstrap目录下包含base.html文件,因为我们后面要用到。

3.Flask-Bootstrap 的初始化

from flask_bootstrap import Bootstrap 
# ...
bootstrap = Bootstrap(app)

4.使用Flask-Bootstrap的模板

初始化 Flask-Bootstrap 之后,就可以在程序中使用一个包含所有 Bootstrap 文件的基模板。
这个模板利用 Jinja2 的模板继承机制,让程序扩展一个具有基本页面结构的基模板,其中
就有用来引入 Bootstrap 的元素。
{% extends "bootstrap/base.html" %}

{% block title%}Flasky{% endblock %}

{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
<div class='container'>
<div class="navbar-header">
<button type="button" class="navbar-toggle"
data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class='icon-bar'></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">Flasky</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="/"></a></li>
</ul>
</div>
</div>
</div>
{% endblock %} {% block content %}
<div class="container">
<div class="page-header">
<h1>Hello,{{ name }}!</h1>
</div>
</div>
{% endblock %}
# 模板利用Bootstrap中的样式进行了修改
Jinja2 中的 extends 指令从 Flask-Bootstrap 中导入 bootstrap/base.html,从而实现模板继
承。Flask-Bootstrap 中的基模板提供了一个网页框架,引入了 Bootstrap 中的所有 CSS 和
模板 | 25
JavaScript 文件。
基模板中定义了可在衍生模板中重定义的块。 block 和 endblock 指令定义的块中的内容可
添加到基模板中。
上面这个 user.html 模板定义了 3 个块,分别名为 title 、 navbar 和 content 。这些块都是
基模板提供的,可在衍生模板中重新定义。 title 块的作用很明显,其中的内容会出现在
渲染后的 HTML 文档头部,放在 <title> 标签中。 navbar 和 content 这两个块分别表示页
面中的导航条和主体内容。
在这个模板中, navbar 块使用 Bootstrap 组件定义了一个简单的导航条。 content 块中有个
<div> 容器,其中包含一个页面头部。之前版本的模板中的欢迎信息,现在就放在这个页
面头部。改动之后的程序如图 3-1 所示。

详解

Flask-Bootstrap基模板中定义的块

块名 说明
doc 整个HTML文档
html_attribs <html>标签的属性
html <html>标签中的内容
head <head>标签中的内容
title <title>标签中的内容
metas 一组标签
styles 层叠样式表定义
body_attribs <body>标签的属性
body <body>标签中的内容
navbar 用户定义的导航条
content 用户定义的页面内容
scripts 文档底部的JavaScript声明

自定义错误页面

利用Jinja2的模板继承机制可以让templates/base.html继承自bootstrap/base.html。
{% extends "bootstrap/base.html" %}

{% block title %}Flasky{% endblock %}

{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">Flasky</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="/">Home</a></li>
</ul>
</div>
</div>
</div>
{% endblock %} {% block content %}
<div class="container">
{% block page_content %}{% endblock %}
</div>
{% endblock %}
程序现在使用的模板继承自templates/base.html不是直接继承自Flask-Bootstrap的基模板。
404错误页面:继承自templates/base.html
{% extends "base.html" %} {% block title %}Flasky - Page Not Found{% endblock %} {% block page_content %}
<div class="page-header">
<h1>Not Found</h1>
</div>
{% endblock %} user页面:继承自templates/base.html
{% extends "base.html" %} {% block title %}Flasky{% endblock %} {% block page_content %}
<div class="page-header">
<h1>Hello, {{ name }}!</h1>
</div>
{% endblock %}

链接

Flask提供了url_for()辅助函数,它可以使用程序URL映射中保存的信息生成URL。
url_for函数最简单的用法:以视图函数名作为参数,返回对应的URL。url_for(‘index’)得到的结果是’/’
使用url_for生成动态地址时,将动态部分作为关键字参数传入。
url_for(‘user’,name=’john’,_external=True)
函数能将任何额外参数添加到查询字符串中。

静态文件

Web 程序不是仅由 Python 代码和模板组成。大多数程序还会使用静态文件,例如 HTML
代码中引用的图片、JavaScript 源码文件和 CSS。
例如,调用
url_for('static', filename='css/styles.css', _external=True) 得 到 的 结 果 是 http://
localhost:5000/static/css/styles.css。
默认设置下,Flask 在程序根目录中名为 static 的子目录中寻找静态文件。如果需要,可在
static 文件夹中使用子文件夹存放文件。服务器收到前面那个 URL 后,会生成一个响应,
包含文件系统中 static/css/styles.css 文件的内容。

示例 展示了如何在程序的基模板中放置 favicon.ico 图标。这个图标会显示在浏览器的
地址栏中。

{% block head %}
{{ super() }}
<link rel="shortcut icon" href="{{ url_for('static', filename = 'favicon.ico') }}"
type="image/x-icon">
<link rel="icon" href="{{ url_for('static', filename = 'favicon.ico') }}"
type="image/x-icon">
{% endblock %}

图标的声明会插入 head 块的末尾。注意如何使用 super() 保留基模板中定义的块的原始
内容。

Flask开发系列之模板的更多相关文章

  1. Flask开发系列之Web表单

    Flask开发系列之Web表单 简单示例 from flask import Flask, request, render_template app = Flask(__name__) @app.ro ...

  2. Flask开发系列之快速入门

    Flask开发系列之快速入门 文档 一个最小的应用 调试模式 路由 变量规则 构造 URL HTTP 方法 静态文件 模板渲染 访问请求数据 环境局部变量 请求对象 文件上传 Cookies 重定向和 ...

  3. Flask开发系列之数据库操作

    Flask开发系列之数据库操作 Python数据库框架 我们可以在Flask中使用MySQL.Postgres.SQLite.Redis.MongoDB 或者 CouchDB. 还有一些数据库抽象层代 ...

  4. Flask开发系列之Flask+redis实现IP代理池

    Flask开发系列之Flask+redis实现IP代理池 代理池的要求 多站抓取,异步检测:多站抓取:指的是我们需要从各大免费的ip代理网站,把他们公开的一些免费代理抓取下来:一步检测指的是:把这些代 ...

  5. Flask开发系列之初体验

    Flask开发初探 介绍 在日常开发中,如果需要开发一个小型应用或者Web接口,一般我是极力推崇Flask的,主要是因为其简洁.扩展性高. 从这篇文章开始,我会写一个关于Flask的系列文章,通过多个 ...

  6. Flask入门系列(转载)

    一.入门系列: Flask入门系列(一)–Hello World 项目开发中,经常要写一些小系统来辅助,比如监控系统,配置系统等等.用传统的Java写,太笨重了,连PHP都嫌麻烦.一直在寻找一个轻量级 ...

  7. flask开发restful api系列(8)-再谈项目结构

    上一章,我们讲到,怎么用蓝图建造一个好的项目,今天我们继续深入.上一章中,我们所有的接口都写在view.py中,如果几十个,还稍微好管理一点,假如上百个,上千个,怎么找?所有接口堆在一起就显得杂乱无章 ...

  8. iOS开发系列--App扩展开发

    概述 从iOS 8 开始Apple引入了扩展(Extension)用于增强系统应用服务和应用之间的交互.它的出现让自定义键盘.系统分享集成等这些依靠系统服务的开发变成了可能.WWDC 2016上众多更 ...

  9. Win10 UWP开发系列:使用VS2015 Update2+ionic开发第一个Cordova App

    安装VS2015 Update2的过程是非常曲折的.还好经过不懈的努力,终于折腾成功了. 如果开发Cordova项目的话,推荐大家用一下ionic这个框架,效果还不错.对于Cordova.PhoneG ...

随机推荐

  1. C# base64 加密解密

    1.base64  to  string string strPath = "aHR0cDovLzIwMy44MS4yOS40Njo1NTU3L1 9iYWlkdS9yaW5ncy9taWR ...

  2. spark中使用的内存文件系统-Tachyon FS 简介

    转自:http://blog.csdn.net/u014252240/article/details/41810849  发布人:南京大学PASA大数据实验室顾荣 1. Tachyon是什么 Tach ...

  3. -fPIC编译选项

    -fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置 ...

  4. zoopkeeper 的ACL操作

    1.创建一个变量存放模式信息, private static final String MODE = "digest"; //ACL模式   2.在一个类的构造函数内放入初始化信息 ...

  5. 8.6培训 D1

    今天是赵和旭老师讲课(也是 zhx) 动态规划 利用最优化原理把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解(有点像分治?) 更具体的,假设我们可以计算出小问题的最优解,那么我们凭 ...

  6. Android Intent和IntentFilter详解与使用及实现系统“分享”接口

    Intent Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作.动作涉及数据.附加数据进行描述,Android则根据此Intent的描述,负责找到 ...

  7. 在CentOS7上搭建Kubernetes

    来源 中文教程 http://blog.51cto.com/devingeng/2096495?from=singlemessage 官方文档 https://kubernetes.io/docs/s ...

  8. js中的break,continue和return的用法及区别

    为什么要说个?好像很简单,但是我也会迷糊,不懂有时候为什么要用return,然而break和continue也经常和他放在一起. 所以就一起来说一说,这三个看起来很简单,却常常会出错的关键词的具体用法 ...

  9. php配置 php-cgi.sock使用

    PHP配置文件: [global]pid = /run/php-fpm/php-fpm.piderror_log = /var/log/php-fpm/php-fpm.loglog_level = n ...

  10. redis主从+哨兵模式(借鉴)

    三台机器分布 192.168.189.129  //  master的角色 192.168.189.130  //  slave1的角色 192.168.189.131  //  salve2的角色 ...