1、jinja2模版过滤器
1.1模板内置的过滤器
{{想要过滤的对象|使用的是什么过滤方法([*args])}}
例如{{name|length}}:将返回字符串的长度,而jinja2的过滤器就相当于是定义了很类似于length这样的函数,我们可以根据这些函数的特定功能来过滤出自己想要的数据。
①html模板代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<p>{{username}}</p>
<p>{{age|abs}}</p>
<p>{{name|default('这个人很懒什么都没有留下')}}</p>
{% autoescape off %}
<p>{{es}}</p>
{% endautoescape %}
<p>{{es|safe}}</p>
<p>{{books.1}}</p>
<p>{{books|first}}</p>
<p>{{books|first|length}}</p>
<p>{{books|last}}</p>
<p>{{books|length}}</p>
<p>{{books|replace('新值','老值')}}</p>
<p>{{books|truncate(length=3)}}</p>
<!--
abs返回一个数值的绝对值。
default如果当前变量没有值,则会使用参数中的值来代替。
safe和autoescape功能一样都是防止flask将html语义转义,让html标签正常显现,标记字符是安全的
flask模板会自动将<>等含有html语义的标签转义,防止页面发生冲突这时候就可以用autoescape来防止转义
first:返回一个序列的第一个元素。last:最后一个。length:序列长度。可复用
format:格式化字符串。例如以下代码{{ "%s" - "%s"|format('Hello?',"Foo!") }}将输出:Helloo? - Foo!
join(value,d='u'):将一个序列用d这个参数的值拼接成字符串。
int(value):将值转换为int类型。
float(value):将值转换为float类型。
lower(value):将字符串转换为小写。
upper(value):将字符串转换为小写。
replace(value,old,new): 替换将old替换为new的字符串,如果替换的字符不存在是不会报错的,但是也不会显示,只有语法层面报错了,才会再页面中报错。
truncate(value,length=255,killwords=False):截取length长度的字符串,最小长度为3,常用作文章的标题,显示的字符为length-3之后为...。
striptags(value):删除字符串中所有的HTML标签,如果出现多个空格,将替换成一个空格。
trim:截取字符串前面和后面的空白字符。
string(value):将变量转换成字符串。
wordcount(s):计算一个长字符串中单词的个数。
-->
</body>
</html>
②python的py代码如下,引用的是上述的html文件
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
context = {
'username': 'beiyue',
'age': -18,
'home': 'shanxi',
'name': 'wcc',
'es': "<script>alert('hello world')</script>",
's': "alert('hello world')",
'books':['python','php','java']
}
return render_template('index.html', **context)
if __name__ == '__main__':
app.run(debug=True)
1.2自定义的过滤器
自定义一个过滤器实现,测试发表时间离当前时间有多久,模拟微信朋友圈发表动态的时间显示,几分钟之前、几小时之前、几天之前
from flask import Flask, render_template
from datetime import datetime
app = Flask(__name__)
@app.route('/')
def index():
context = {
'username': 'hello beiyue',
'age': -18,
'home': 'shanxi',
'name': 'wcc',
'es': "<script>alert('hello world')</script>",
's': "alert('hello world')",
'books':['python','php','java'],
'now_time':datetime(2020,4,10,16,0,0)
}
return render_template('index.html', **context)
@app.template_filter('my_cut')
def cut(value):
return value.replace('hello', '')
# handle_time是自定义的模板过滤器的名字
@app.template_filter('handle_time')
def handle_t(time):
'''
小于一分钟=>显示刚刚
大于一分钟小于一小时=>显示xx分钟之前
大于一小时小于二十四小时=>显示xx小时之前
:param time:
:return:
'''
if isinstance(time,datetime):
now = datetime.now()
timestamp = (now-time).total_seconds() # 得到时间的总秒数
if timestamp<60:
return '刚刚'
elif timestamp >=60 and timestamp <= 60*60:
return '%s分钟之前'.format(int(timestamp/60))
elif timestamp>=60*60 and timestamp<=60*60*24:
return '%s小时之前'.format(int(timestamp/(60*60)))
else:
return '很久之前'
else:
return time
if __name__ == '__main__':
app.run(debug=True)
2、控制语句
下面的例子有if和for两种例子,for语句无法使用continue和break,页面不会显示但是也不会报错
下面是定义tab键自动补全html代码的设置
3、宏和import语句
3.1宏
模板中的宏跟python中的函数类似,可以传递参数,但是不能有返回值,可以将一些经常用到的代码片段放到宏中,然后把一些不固定的值抽取出来当成一个变量,例如input标签,定义在宏中input就变成一个函数了,想调用的时候就可以直接调用,和input没有本质区别,显示都是一样的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% macro input(name, value='', type='text') %}
<input type="{{ type }}", name="{{name}}", value="{{value}}">
{% endmacro %}
<table>
<tr>
<td>用户名:</td>
<td><input type="text"></td>
<td>用户名:</td>
<td>{{input('username')}}</td>
<td>密码:</td>
<td>{{input('password',type='password')}}</td>
<td>按钮:</td>
<td>{{input(value='提交',type='submit')}}</td>
</tr>
</table>
</body>
</html>
3.2import语句
在真实的开发中,会将一些常用的宏单独放在一个文件(只能写在html里)中,宏中可以只写宏定义的函数,使用的时候,从文件中进行导入。直接import…as…,也可以from…import…或者from…import…as…,导入的时候是以templates作为根目录的,根据前文按照flask模板创建目录格式
①import…as…
{% import 'macro.html' as macro with context %}
with context是将py文件中定义的变量字段引入到宏中显示,相当于传参
<tr>
<td>用户名:</td>
<td>{{ macro.input('username') }}</td>
</tr>
②from…import…或者from…import…as…
{% from "macro.html" import input %}
<tr>
<td>密码:</td>
<td>{{ input("password",type="password") }}</td>
</tr>
4、include和set语句
4.1include语句
同一页面跳转之间,头部标签还有尾部标签可能都是一样的,可以把这些重复的代码写在一个模板里面,想要使用的时候通过include来调用,避免代码的冗余,提高代码的复用性,这是基于flask的模板创建的基于templates模板写的绝对路径,要按照flask框架的结构书写代码才可以正确的使用
{% include 'commit/header.html' %}
主体内容
{% include 'footer.html' %}
主题内容
4.2set语句
如果在模板中定义了一个变量只能通过py文件来渲染,如果想要自定义变量则可以使用set语句,使用了这个即使py文件传过来变量值也不会渲染,只会显示模板中的变量
{% set name='beiyue' %}
<p>{{ name }}</p>
此时name相当于全局修改变量,只要是name都会变成beiyue,可以通过with语句来创建一个内部的作用域,将set语句放在其中,这样创建的变量只在with代码块中才有效,如果两个变量名一样全局的不会影响局部,局部的会显示自定义的变量内容
{% with %}
{% set age = 2 %}
{{ age }} 2
{% endwith %}
{{age}} 22
{% with name = 'wccc' %}
{{ name }}
{% endwith %}
一次只能定义一个变量,变量可以为字符串、字典、列表,但是定义多了会报错,如果想要定义多个变量,可以写多个set