python jinjia2 使用语法
简介
对于jinjia2来说,模板仅仅是文本文件,可以生成任何基于文本的文件格式,例如HTML、XML、CSV、LaTex 等等,以下是基础的模板内容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul>
{% for item in seq %} {# test #}
<li>{{ item }}</li>
{% endfor %}
</ul>
</body>
</html>
其中{% %}是用来执行表达式或者赋值,{{ }}则是用来显示对应变量的值,可以是表达式中的值,也可以是应用传入的值,{# #}相当于是python的注释,这个是模板中的注释。除此之外,这些标识符都可以在Environment中进行自定义修改,不过一般不会修改。
变量
众所周知,模板文件中存在表达式和变量,那么变量是怎么来的呢?当然是在调用render渲染模板时传入的,那么变量有哪几种类型呢?
1.普通值
模板文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>{{name}}</h1>
<h2>{{gender}}</h2>
</body>
</html>
调用模板文件传递普通值(存在、不存在)以及不传部分值
from jinja2 import Environment, FileSystemLoader
import pathlib
TEMPLATE_PATH = (
pathlib.Path(__file__).parent.joinpath("template_demo").joinpath("templates")
)
env = Environment(loader=FileSystemLoader(TEMPLATE_PATH))
template = env.get_template("template.html")
# 如下两种方式都可以进行传递
# data = template.render(name="tom", age=18)
data = template.render({"name": "tom", "age": 18})
print(data)
结果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>tom</h1>
<h2></h2>
</body>
</html>
由结果可以看出,当传递一个不存在值或者不传递模板中所需要的值时,默认的值为空
2.字典
模板文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul>
<li>{{ item.name }}</li>
<li>{{ item.age }}</li>
<li>{{ item['gender'] }}</li>
</ul>
</body>
</html>
调用模板文件传递字典(值存在、不存在)以及不传部分值
from jinja2 import Environment, FileSystemLoader
import pathlib
TEMPLATE_PATH = (
pathlib.Path(__file__).parent.joinpath("template_demo").joinpath("templates")
)
env = Environment(loader=FileSystemLoader(TEMPLATE_PATH))
template = env.get_template("template2.html")
data = template.render(item={"name": "tom", "gender": "man", "city": "nanjing"}, age=18)
print(data)
结果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul>
<li>tom</li>
<li></li>
<li>man</li>
</ul>
</body>
</html>
由结果可以看出,与普通值类似,当传递一个不存在值或者不传递模板中所需要的值时,默认的值为空。
需要注意的是当传入字典时,在模板文件中有两种方式可以接收字典的值,一种是item.attr,另一种是item['attr'],这两种效果是一致的,在官方文档中说明有如下:
Jinja2 中 item.attr 在 Python 层中做下面的事情:
检查 item 上是否有一个名为 attr 的属性。
如果没有,检查 item 中是否有一个 'attr' 项 。
如果没有,返回一个未定义对象。
item['attr'] 的方式相反,只在顺序上有细小差异:
检查在 item 中是否有一个 'attr' 项。
如果没有,检查 item 上是否有一个名为 attr 的属性。
如果没有,返回一个未定义对象。
如果一个对象有同名的项和属性,这很重要。此外,有一个attr()过滤器,它只查找属性。
那么什么情况下会出现同名的项和属性呢,如下
class Person(object):
def __init__(self, name, age, gender) -> None:
self.name = name
self.age = age
self.gender = gender
self.data = {"name": "mike"}
def __getitem__(self, key):
print('__getitem__')
return self.data[key]
def __setitem__(self, key, value):
print('__setitem__')
self.data[key] = value
def __delitem__(self, key):
print('__delitem__')
del self.data[key]
p = Person("tom", "123", "man")
print(p.name)
print(p['name'])
tom
__getitem__
mike
p.name与p['name']分别是由不同的内置函数所控制的,p.name是由__setattr __、__getattr __将对应数据从__dict__中添加或者获取,p['name']是由__getitem __、__setitem __、__delitem __将对应数据从自定义字典中添加或获取、删除,只需要保证二者对应的字典中出现重名的即可。
3.序列(列表、集合、元组等)
模板文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul>
{% for item in seq %}
<li>{{ item }}</li>
{% endfor %}
</ul>
</body>
</html>
调用模板文件传递字典(值存在、不存在)以及不传部分值
from jinja2 import Environment, FileSystemLoader
import pathlib
TEMPLATE_PATH = (
pathlib.Path(__file__).parent.joinpath("template_demo").joinpath("templates")
)
env = Environment(loader=FileSystemLoader(TEMPLATE_PATH))
template = env.get_template("template3.html")
data = template.render(seq=[1, 2, 3, 4], item=[1, 2, 3])
print(data)
结果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</body>
</html>
由结果可以看出,与上述类似,当传递一个不存在值或者不传递模板中所需要的值时,默认的值为空(如果处于循环中则不显示)。除此之外,序列中元素可以在模板中进行遍历。
4.自定义对象
对象就可以是上述字典中所描述的重名对象,
模板文件如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul>
<li>{{ item.name }}</li>
<li>{{ item['name'] }}</li>
<li>{{ item.age }}</li>
<li>{{ item['gender'] }}</li>
</ul>
</body>
</html>
调用模板文件传递对象
p = Person("tom", "123", "man")
print(p.name)
print(p['name'])
TEMPLATE_PATH = (
pathlib.Path(__file__).parent.joinpath("template_demo").joinpath("templates")
)
env = Environment(loader=FileSystemLoader(TEMPLATE_PATH))
template = env.get_template("template4.html")
data = template.render(item=p)
print(data)
结果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul>
<li>tom</li>
<li>mike</li>
<li>123</li>
<li>man</li>
</ul>
</body>
</html>
由结果可见,item.name与item['name']虽然同名,但是不同值,当然可以使用attr过滤器只查询属性,只需要将变量改为如下方式,就只会获取到属性,详细用法到下面过滤器再进行说明。
<li>{{ item|attr("name")}}</li>
过滤器
顾名思义,就是对传入模板的变量进行过滤得到符合要求的信息,过滤器的基本用法如下
item|过滤器(参数)
例如获取对象的属性:
item|attr("name")
除此之外,过滤器还支持多条件过滤,每一次过滤后的结果作为下一个过滤器的参数,例如
将值进行绝对值后再转变成浮点型
{{ item.sale|abs|float}}
内置过滤器如下:
| 过滤器名称 | 过滤器的作用 | 使用方法 |
|---|---|---|
| abs(number) | 返回number的绝对值 | item|abs |
| attr(obj, name) | 获取obj的name属性,类似于obj.name | foo|attr("bar") |
| batch(value, linecount, fill_with=None) | 批处理value的过滤器,value必须为可迭代对象(字典、字符串、列表、字典等),根据linecount将value分成多个linecount个数的块,不够的使用fill_with的参数补全,返回的是一个生成器。 |
item|batch(2, ' ') |
| capitalize(s) | 将字符串s首字母大写 |
item|capitalize |
| center(value, width=80) | 将value值在width字符中居中, 默认width为80 | item|center(20) |
| default(value, default_value=u'', boolean=False) | 当value未传值时显示default_value默认值,需要注意当value为空字符串时,default_value将不会显示,需将boolean设置为true才会显示 | item|default("test") |
| dictsort(value, case_sensitive=False, by='key') | 将value字典按照键值对的形式形成元组并排序添加到列表中,类似于[('age', 10), ('name', 20)],case_sensitive:排序时是否区分大小写,by:排序的依据,默认为key |
item|dictsort(true) |
| escape(s) | 将特殊字符( &, <, >, ‘, ”)转换成安全的html,就是转义 | item|escape |
| filesizeformat(value, binary=False) | 将文件格式化成人类可读的文件大小,默认十进制,binary为true时使用二进制 | item\filesizeformat |
| first(seq) | 返回序列的第一个元素 | item|first |
| float(value, default=0.0) | 将value转为浮点类型,默认为0.0 | ite|float |
| forceescape(value) | 强制value html转义 | item|forceescape |
| format(value, *args, **kwargs) | 格式化字符串 | {{ "%s - %s"|format("Hello?", "Foo!") }} Hello? - Foo! |
- batch(value, linecount, fill_with=None)详解
当前存在如下模板文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<table>
{{item}}
{{item|batch(2, ' ')|list}}
{%- for row in item|batch(2, ' ') %}
<tr>
{%- for column in row %}
<td>{{ column }}</td>
{%- endfor %}
</tr>
{%- endfor %}
</table>
</body>
</html>
python代码
from jinja2 import Environment, FileSystemLoader
import pathlib
TEMPLATE_PATH = (
pathlib.Path(__file__).parent.joinpath("template_demo").joinpath("templates")
)
env = Environment(loader=FileSystemLoader(TEMPLATE_PATH))
template = env.get_template("template5.html")
data = template.render(item="asdadsa")
print(data)
结果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<table>
asdadsa
[['a', 's'], ['d', 'a'], ['d', 's'], ['a', ' ']]
<tr>
<td>a</td>
<td>s</td>
</tr>
<tr>
<td>d</td>
<td>a</td>
</tr>
<tr>
<td>d</td>
<td>s</td>
</tr>
<tr>
<td>a</td>
<td> </td>
</tr>
</table>
</body>
</html>
由结果可以看见,将传入的asdadsa变为了[['a', 's'], ['d', 'a'], ['d', 's'], ['a', ' ']],item|batch(2, ' ')将传入值按照每两个一组的形式,缺少的使用 补充,由此形成了一个内部嵌套可迭代对象的生成器,需要使用两次for循环获取数据,此处是因为使用了list转变成了列表。这方法非常适用于数据中存在分段数据格式需要统一(例如表格中的数据,可以传入所有数据,分块自动显示数据)。
测试
测试主要是测试一个变量或者一个表达式,使用is
注释
在模板中使用注释,需要注意,原有的模板文件的格式注释不适用,需要使用{# #},也可以自定义注释的风格,使用Environment中的comment_start_string和comment_end_string进行修改,注意需要首尾呼应。
空白控制
默认情况下,模板引擎不会对模板中的空白做任何修改,如果应用配置了Environment的 trim_blocks ,模板标签后的第一个换行符会被自动移除。
此外,也支持手动将空白删除,只需在需要的块前或者块后添加-即可,例如,清除了for之前的空白及属性后的空白,需要注意的是标签与-之间不能留空白。
{%- for i in item %}
{{i}}
{%- endfor %}
转义
当希望Jinjia2忽略某些变量或者块、标签时,尤其是内置的标签,例如当你需要显示{{,使用{{ {{ }}会报错,需要使用{{ '{{' }}
如果对于较大的块的话,例如想在网页展示jinjia2的语法,如下,使用{% raw %}和{% endraw %}包裹即可。
{% raw %}
<ul>
{% for item in seq %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{% endraw %}
行语句
使用Enviroment的block_start_string和block_end_string设置行语句前缀为#时,默认会清除行首的空白,如下两种方式是一致的, 需要注意的是当启用行语句后,除了#后面的逻辑操作之外,不建议在同一行进行其他操作。
<ul>
# for item in seq
<li>{{ item }}</li>
# endfor
</ul>
<ul>
{% for item in seq %}
<li>{{ item }}</li>
{% endfor %}
</ul>
若有未闭合的圆括号、花括号或方括号,行语句可以跨越多行:
<ul>
# for href, caption in [('index.html', 'Index'),
('about.html', 'About')]:
<li><a href="{{ href }}">{{ caption }}</a></li>
# endfor
</ul>
除了行语句之外还有行注释,使用Environment中的comment_start_string和comment_end_string修改即可设置行注释, 例如修改为#, #之后的都将作为注释。
python jinjia2 使用语法的更多相关文章
- python yield from 语法
python yield from 语法 yield语法比较简单, 教程也很多 , yield from的中文讲解很少 , python官网是这样解释的 PEP 380 adds the yield ...
- Python基础:语法基础(3)
本篇主要介绍Python中一些基础语法,其中包括:标识符.关键字.常量.变量.表达式.语句.注释.模块和包等内容. 1. 标识符和关键字 1.1 标识符 标识符是变量.常量.函数.属性.类.模块和包等 ...
- Python的基础语法(二)
0. 前言 接着上一篇博客的内容,我将继续介绍Python相关的语法.部分篇章可能不只是简单的语法,但是对初学者很有帮助,也建议读懂. 1. 表达式 由数字.符号.括号.变量等组成的组合. 算术表达式 ...
- 六. Python基础(6)--语法
六. Python基础(6)--语法 1 ● Python3中, Unicode转字节的方法 print(bytes("李泉", encoding = 'utf-8')) prin ...
- 五. Python基础(5)--语法
五. Python基础(5)--语法 1 ● break结束的是它所在的循环体, continue是让它所在的循环体继续循环 # 打印: 1 10 2 10 3 10 4 10 5 10 6 10 7 ...
- 四. Python基础(4)--语法
四. Python基础(4)--语法 1 ● 比较几种实现循环的代码 i = 1 sum = 0 while i <= 10: # 循环10-1+1=10次 sum += i i ...
- 三. Python基础(3)--语法
三. Python基础(3)--语法 1. 字符串格式化的知识补充 tpl = "我是%s,年龄%d,学习进度100%" %('Arroz',18) print(tpl) # 会提 ...
- 二. Python基础(2)--语法
二. Python基础(2)--语法 1.实现一个简单的登录系统 '''# 形式1 n = 1 while n < 4: name = input("请输入姓名\n" ...
- 一. Python基础(1)--语法
一. Python基础(1)--语法 1. 应用程序 1.1 什么是计算机(Computer)? 组成 ①运算器 arithmetic unit; ※ Arithmetic unit and cont ...
随机推荐
- Oracle 19c单实例部署
目录 Oracle 19c单实例部署: 1.配置yum: 2.安装rpm包: 3.设置hostname: 4.配置hostname解析: 5.配置时钟同步服务(ntp): 6.检查及配置内核参数: 7 ...
- 一起看 I/O | Flutter 3 正式发布!
作者 / Tim Sneath, Google Flutter 和 Dart 产品组产品经理 Flutter 3 实现了 Flutter 以移动端为中心扩展到多平台的产品规划,并在今年 I/O 大会的 ...
- 109_Power Pivot客户ABC(帕累托)分析度量值写法(非计算列)
博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 1.背景 客户ABC分析,一般的套路是在计算列中把客户ABC分类,便于后续维度使用.今天用度量值的方式写一个ABC的分类. ...
- java框架--快速入门
spring快速入门 1.创建项目 1.1创建项目文件夹 1.2启动idea ->文件->打开->点击创建的项目文件夹 1.3右键创建 ...
- declare-声明限定类型变量
用于声明变量并设置变量的属性. 语法 declare [+/-][rxi][变量名称=设置值] declare -f 特殊符号 +/- "-"可用来指定变量的属性,"+& ...
- React简单教程-6-单元测试
前言 我想大部分人的前端测试,都是运行项目,直接在浏览器上操作,看看功能正不正常.虽然明明有测试库可以使用,但是因为"要快"的原因,让好好做测试变成了一件影响效率的事. 因为这种无 ...
- 更换conda镜像源、pip镜像源
镜像源一般有两点特别需要注意,一个是Conda源,一个是Pip源: 更换Conda源,以更换清华Conda源为例: Anaconda 镜像使用帮助 Anaconda 是一个用于科学计算的 Python ...
- Lucene从入门到实战
Lucene 在了解Lucene之前,我们先了解下全文数据查询. 全文数据查询 我们的数据一般分为两种:结构化数据和非结构化数据 结构化数据:有固定格式或有限长度的数据,如数据库中的数据.元数据 非结 ...
- SQL注入漏洞篇
一篇SQL注入漏洞汇总,更新中-- 如有缺陷 望大佬指正 SQL注入产生的原因? 当程序执行逻辑时没有对用户输入的参数做过滤处理,使参数直接与后台数据库产生逻辑交互,即SQL注入黑客就可以利用各种SQ ...
- BUUCTF-九连环
九连环 这题还是稍微有点难度的 使用16进制打开发现压缩包,用binwalk分离看看 分离得到的压缩包同样16进制看看 可以发现多个压缩包,这种情况应该是伪加密的方式,但是直接使用修复压缩包的方式没法 ...