【Flask】 Jinja2模板语言
Jinja2
Jinja2是Python Web编程中的主流模板语言。因为flask是基于Jinja2和Werkzeug发展而来,在安装flask的时候jinja2自动就被装在上面了。
之前提到了很多Jinja2的使用方法啊,下面将补充或者更加详细地说明Jinja2作为模板语言的使用。
【Jinja2官方文档】http://docs.jinkan.org/docs/jinja2/
■ 基本语义
看过之前模板的例子就知道,Jinja2做构成的模板文件中,文本内容大致可以分成几个种类。比如特殊文本(不进行转义,比如HTML,XML格式的文本)、{{ }}表示的变量或者宏调用、{% %}表示逻辑控制,{# #}表示注释,其中内容不被模板引擎转义。
■ set语句赋值
在之前的所有例子中,模板中变量的值似乎只有一个来源,就是来自于后端的提供。但是实际上我们可以在模板这个层面对变量进行赋值,就是通过了{% set variable_name="value" %}的形式。这赋予了模板在内部进行变量赋值的能力,提高了灵活性。如果想要set一个变量的值为某个函数的返回值的话,那么那个函数不用{{ }}包着。比如{% set action_view = url_for('main.upload') %}而不是{{ url_for('main.upload') }}。
■ 过滤器
Jinja2可以使用过滤器,对传入模板的第一手数据进行二次加工。过滤器的形式是以管道符号连接第一手数据和二次处理数据的方法。比如在模板中写:
{{ my_variable|default("my_variable is not defined") }}
的意思就是说在此处的第一手数据是由后端传过来的my_variable这个变量的值。如果这个变量没有被定义,那么就有default过滤器方法指定了它没有被定义时应该显示什么东西。过滤器方法有很多很多,各种各样的过滤器方法使得数据从后端传入前段之后还能再进行灵活的操作,从而提高了整个编程的便利性和敏捷性。其他常用或者我看着比较有用的过滤器方法还有:
****以下说明中的第一个参数都是指通过管道传过去的值,实际写在管道右边的方法参数应该比下面说明中的少一个,就像python面向对象编程中的self参数那样的感觉****
attr(object,name) 比如account|attr("name")中account预期是一个字典(或者按照JS的说法是一个object),此时这个地方就是现实account['name']的值
capitalize(s) 把字符串的首字母大写,后面的全部小写
default(value,default_value=u'',boolean=False) 设置默认值,如果没有给出value,那么就用default_value的值(即空字符串)
filesizeformat(value,binary=False) 接受一个数值然后转化成容易阅读的字节形式比如1.3MB,305Byte等,比如{{ size|filesizeformat() }}
float(value,default=0) 接受一个值并将其转化为float类型
escape(string) 把字符串中HTML特殊字符比如<,>,&等反转义成HTML的表达方式
groupby(value,attribute) 按照指定的共有属性将(一个字典组成的列表)集合进行分组,返回一个字典组成的列表。这个列表中的每个字典都有两项,第一项的key是grouper然后value是根据groupby区分后得到的那个原字典中key的值。说了一串自己都晕了,下面给个例子。。
比如模板是这个样子的:
<ul>
{% for group in persons|groupby('gender') %}
<li>{{ group.grouper }}<ul>
{% for person in group.list %}
<li>{{ person.first_name }} {{ person.last_name }}</li>
{% endfor %}</ul></li>
{% endfor %}
</ul>
而作为persons传入的数据lst是这个样子的:
lst = []
lst.append({"gender":"male","first_name":"Frank","last_name":"Takanashi"})
lst.append({"gender":"female","first_name":"Bob","last_name":"Kazuya"})
lst.append({"gender":"female","first_name":"Ocean","last_name":"King"})
那么最终得到渲染完成的文件是长这个样子的:
<ul>
<li>female
<ul>
<li>Bob Kazuya</li>
<li>Ocean King</li>
</ul>
</li>
<li>male
<ul>
<li>Frank Takanashi</li>
</ul>
</li>
</ul>
int(value,default) 把值转化为一个int类型
join(value,sep=u'') 接受一个序列类型的对象,然后通过sep指定的字符将所有序列元素连接在一起成为一个字符串。sep默认是空字符串
last/first/random(seq) 返回序列的最后/最前/随机一个元素
replace(string,old,new,count=None) 接受一个字符串,将其中的old部分全部转化为new,从左到右替换count次,如果不指定count是只替换第一个扫描到的
reverse(value) 接受一个可迭代对象,然后返回其反序序列的迭代器
sort(value,reverse=False,case_sensative=False,attribute=None) 对可迭代的对象进行排序,默认情况下以升序大小写不敏感的方式排序。
striptags(value) 把一段比如XML格式的文本中的标签都去掉
sum(iterable,attribute=None,start=0) 对可迭代对象进行求和,如果需要对其某个特定属性的值求和的话可以设置attribute属性
title(string) 将字符串转换为标题格式显示
trim(value) 去除开头和末尾的所有空格,相当于strip()
truncate(s,length=255,killwords=False,end='...') 这是个比较有有意思的方法,它把字符串转化成简略形式,比如"foo bar"|truncate(5)可以得到foo ...,如果"foo bar"|truncate(5,True)可以得到foo b...
round(value,precision=0,method='common') 对数字进行四舍五入,precision表示小数点后保留几位。method除了common是四舍五入规则外,floor是向下抹平,ceil是向上抹平。
* 今天遇到了round的一个坑,就是需要注意round前面的东西一定要是一个整体。当然1.23|round之类,直接写数字没问题,当使用算式时请注意一定要把算式用括号括起来才能使过滤器有效。比如 num/1024.0 | round是不会有四舍五入之类的效果的,只有(num/1024.0) | round才行。
wordcount(s) 计算字符串中单词的个数
以上还不是过滤器方法的全部,一般而言这些处理都可以放在python中做,python也可以做的非常好,但是这样的话势必要往模板中传递很多很多变量。如果可以在模板这个层面对这些数据进行一些二次处理的话就可以让后端和前端之间的交互体量变小,提高编程的便利性。
■ 逻辑结构
Jinja2中和一般编程语言中一样,可以有if/else,for,is等等关键字作为逻辑控制的节点。而这些关键字必须是放在{% %}或者{{ }}里面的。
● is关键字判断条件
利用is关键字和所谓的“测试方法”可以获得一个布尔值,从而利用其进行一些逻辑判断。比如{{ name is defined }}可以返回True/False来体现name这个变量是否被定义了。类似的“测试方法”还有:
callable(object) 检查一个对象是否可调用
defined/undefined(object) 检查一个对象是/否被定义了
divisibleby(value,num) 检查value能否被数字num整除
escaped(value) 检查一个对象是否被转码了
iterable(value) 检查一个对象是否可迭代
lower/upper(value) 检查一个对象是否都小/大写
none(value) 检查一个对象是否是None
number(value) 检查一个对象是否是数字
sameas(value,other) 检查一个对象是否和other这个对象是同一个对象
用法:{% if loop.index is divisibleby(3) %}就表示如果loop.index这个值能够被3整除的话就进入这个逻辑分支
除了上面这些带参数的判断条件,也有一些不带参数的条件,在Jinja2里被称为测试器(test)。比如:
defined/none 检查一个对象是否被定义,其实效果和{% if var %}是一样的
upper/lower 检查一个字符串对象是否都是大写或小写
string {% if var is string %}检查对象是不是一个字符串
odd/even 检查一个整数对象是否是奇/偶数
iterable 检查一个对象是不是可迭代对象,简单来说就是看是不是列表之类的序列类型
mapping 检查一个对象是不是k-v对形式的对象,比如字典
● 自定义测试器
如果内置的一些测试器不能满足我们的需求,那么我们可以自定义一些测试器。具体的做法是在python代码中写一个测试函数,然后用app.add_template_test方法把这个测试器和app对象关联起来。比如下面这个:
def over_five(string):
#接受的一定是一个字符串对象,然后可以在函数中对这个字符串做出处理
return int(string) > 5 app.add_template_test(over_five,'my_test') '''
然后在模板中就可以这么用了:
{% if num is my_test %}
<p>{{ num }} is bigger than 5</p>
{% else %}
<p>{{ num }} is smaller than 5</p>
{% endif %}
'''
● 判断语句
判断语句没什么好说的了,反正就是{% if ... %}{% elif ... %}{% else %}{% endif %}的格式。
● 循环语句
Jinja2中的循环只能通过for语句,而且不具备break,continue之类的循环控制功能。但是在for循环的作用域内,可以访问特殊对象loop的一些属性来获得循环的一些信息。loop具有以下属性:
loop.index 当前循环迭代的次数(从1开始计数)
loop.index0 从0开始计数的循环迭代次数
loop.revindex 到循环结束为止需要迭代的次数
loop.first 是否是第一次迭代
loop.last 是否是最后一次迭代
loop.length 序列中项目的数量
loop.cycle 在一串序列间取值的辅助函数
比如下面这个代码的用例:
{% for user in users %}
<li>
{% if not loop.first %}
{{ user.username }}
{% endif %}
</li>
{% endfor %}
就是说假如是循环中的第一个,就不显示它的username了。
■ 模板继承
之前在简介中也说过好多次,jinja2的模板是可以进行继承的。采用关键字{% extends "parent.html" %}的形式。
父模板中可以有多个不重名的{% block xxx %}{% endblock %},在子模板中通过{% block xxx %}可以指定修改某个block中的内容。更加详尽的内容都写在flask的大概介绍里,就不重复了。
■ 独立使用jinja2
jinja2作为一个插件很广泛地用于flask,django等框架中。但是也不能忘记,jinja2本身就是一个python的模块。在非框架的环境中,我们也可以通过其API单独进行jinja2的调用。常用的方法是这样子的:
from jinja2 import Template
t = Template('Hello, {{ name }}')
print t.render(name='Frank')
# 输出 Hello, Frank
可以看到,通过给Template类传递一段模板代码,然后调用其render方法,并且给出模板中变量的定义,就可以得到渲染出来的代码了。但是这样有一点不好就是要把模板内容全部写出来,最好是有传递文件名来指定一个模板的。这就要用到jinja2中的Envrionment和Loader两个概念:
from django import Environment,FileSystemLoader
env = Environment(loader=FileSystemLoader('/path/to/directory'))
t = env.get_template('test.html')
print t.render(name='Frank')
# 将模板文件test.html按照给出的参数进行渲染
/path/to/directory是test.html所在的目录,该目录下所有其他文件也可以通过get_template方法来作为一个模板文件获取出来。这里直接写模板文件名说明模板文件就在目录下,如果有多层级目录也可以写/path/to/file.html。FileSystemLoader应该是一个常用的Loader,它将某个指定的目录作为模板的存放目录加入环境中。除了FileSystemLoader以外,还有其他的一些Loader比如PackageLoader,PackageLoader('application','templates')将包application(中有__init__.py文件)中的templates目录作为模板的存放目录。
模板内容渲染成实际代码的逻辑和过程和框架中的jinja2是一样的。
【Flask】 Jinja2模板语言的更多相关文章
- 第四篇flask中模板语言 jinja2
Flask中默认的模板语言是Jinja2 首先我们要在后端定义几个字符串,用于传递到前端 STUDENT = {, 'gender': '中'}, STUDENT_LIST = [ {, 'gende ...
- flask 基本操作 模板语言 session
Django web:优点:大而全,ORM models ,model Form ,admin ,csrf ,session缺点:资源浪费 Flask web:优点:小而精,ORM:x , Form: ...
- flask之jinja2模板语言
一.jinja2简单介绍 Jinja2是Python里一个被广泛应用的模版引擎,他的设计思想来源于Django的模板引擎,并扩展了其语法和一系列强大的功能.其中最显著的一个是增加了沙箱执行功能和可选的 ...
- Python Flask Jinja2模板引擎
模板 简介 模板是一个包含响应文本的文件,其中包含用占位变量表示的动态部分,其具体值只在请 求的上下文中才能知道. 渲染 使用真实值替换变量,再返回最终得到的响应字符串,这一过程 称为渲染.为了渲染模 ...
- [Flask]jinja2模板-宏的使用
定义宏: macros.html <!DOCTYPE html> <html lang="en"> <head> <meta charse ...
- Flask最强攻略 - 跟DragonFire学Flask - 第四篇 Flask 中的模板语言 Jinja2 及 render_template 的深度用法
是时候开始写个前端了,Flask中默认的模板语言是Jinja2 现在我们来一步一步的学习一下 Jinja2 捎带手把 render_template 中留下的疑问解决一下 首先我们要在后端定义几个字符 ...
- python 全栈开发,Day119(Flask初识,Render Redirect HttpResponse,request,模板语言 Jinja2,用户登录例子,内置Session)
一.Flask初识 首先,要看你学没学过Django 如果学过Django 的同学,请从头看到尾,如果没有学过Django的同学,并且不想学习Django的同学,轻饶过第一部分 三大主流Web框架对比 ...
- 第四篇 Flask 中的模板语言 Jinja2 及 render_template 的深度用法
是时候开始写个前端了,Flask中默认的模板语言是Jinja2 现在我们来一步一步的学习一下 Jinja2 捎带手把 render_template 中留下的疑问解决一下 首先我们要在后端定义几个字符 ...
- 3,Flask 中的模板语言 Jinja2 及 render_template 的深度用法
Flask中默认的模板语言是Jinja2 现在我们来一步一步的学习一下 Jinja2 捎带手把 render_template 中留下的疑问解决一下 首先我们要在后端定义几个字符串,用于传递到前端 S ...
随机推荐
- 一个可以自由定制外观、支持拖拽消除的MaterialDesign风格Android BadgeView
为了尊重作者,先放上链接:https://github.com/qstumn/BadgeView BadgeView 一个可以自由定制外观.支持拖拽消除的MaterialDesign风格Android ...
- java.text.ParseException: Unparseable date: "2015-06-09 hh:56:19"
1.错误描述 [DEBUG:]2015-06-09 16:56:19,520 [-------------------transcation start!--------------] java.te ...
- 用vlc搭建简单流媒体服务器(UDP和TCP方式)
.UDP(legacy)传统模式 .RTP方式 .RTSP方式 RTSP方式是通过RTP进行流媒体数据的传输的,VLC的实现也是基于UDP的.这种方式网上的参考资料比较多,我就不截图了,直接叙述命令行 ...
- C# 获取一个独一无二的字符串 GUID
在保存文件,创建目录时,为了保证名称不重复,经常使用Random产生一个随机数,有更简单且不会重复的办法是: Guid.NewGuid().ToString() 就会生成一个类似 37c1acec-4 ...
- PyTorch官方中文文档:torch.Tensor
torch.Tensor torch.Tensor是一种包含单一数据类型元素的多维矩阵. Torch定义了七种CPU tensor类型和八种GPU tensor类型: Data tyoe CPU te ...
- Python爬虫之模拟登录微信wechat
不知何时,微信已经成为我们不可缺少的一部分了,我们的社交圈.关注的新闻或是公众号.还有个人信息或是隐私都被绑定在了一起.既然它这么重要,如果我们可以利用爬虫模拟登录,是不是就意味着我们可以获取这些信息 ...
- RobotFramework下的http接口自动化Set Request Header 关键字的使用
Set Request Header 关键字用来设置http请求时的请求头部信息. 该关键字接收两个参数,[ header_name | header_value ] 示例1:设置http请求时的Re ...
- SPOJ3267:D-query
题面 SPOJ3267 Sol 给定\(N\)个正整数构成的序列,将对于指定的闭区间查询其区间内的不同的数的个数 主席树 不是权值线段树 维护位置 如果插入一个数时发现之前有过了 那么修改当前的,那个 ...
- [BZOJ1016] [JSOI2008] 最小生成树计数 (Kruskal)
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
- Delphi关于TAdvStringGrid控件颜色的设置
FixedFont-Color 标题行和列字体的颜色 Font-color 单元格字体的颜色Visual-color 整个表格的背景色填充