Flask模版 jinjan2
使用模版
- 在渲染模版时,默认会从项目根目录下的
templates文件夹下查找 模版文件 - 可以在 flask 初始化的时候通过
template_folder指定模版目录
模版参数
-
使用
render_template时,可以通过传递关键字参数,在模版中直接使用{{ key }}的方式使用 -
如果参数过多,可以将参数放在 字典中,然后通过
render_template(template_name_or_list, **context)的方式在模版中调用
模版中url_for
通 后台视图函数中的使用方式,在模版中用{{ url_for() }}
过滤器
- 过滤器 通过管道符 (
|) 使用的,例如:{{name | length}}将返回 name 变量的长度。
过滤器相当于一个函数。
jinjan2中内置了许多过滤器 - 基本语法:
{{ 变量名 | 过滤器名称 }}
常用过滤器
-
default()
例如:默认个性签名
<p>个性签名:{{title | default("此人很懒,没有留下签名...",true)}}</p>
或者
<p>个性签名:{{title or "此人很懒,没有留下签名..."}}</p>
自动转义过滤器
-
safe过滤器, 可以关闭一个字符串的转义 -
escape过滤器 ,对某一个字符串进行转义 -
autoescape标签,可以对在它里面的代码块关闭或开启自动转义
{% autoescape off/on %}
<p>个性签名:{{title | escape}}</p>
{% endautoescape %}
length(value)first(value)last(value)join(value,d=u'')-
int(value)/float(value)/string(value) -
upper(value)/lower(value) replace(value,old,new)-
truncate(s, length=255, killwords=False, end='...', leeway=None)截断字符 -
striptags(value)过滤 SGML/XML 标签
等等
自定义过滤器
过滤器本质上就是一个函数,如果调用这个过滤器,就会将模版中的变量当作这个函数的第一个参数,函数的返回结果就是 过滤之后的结果,实现自定义过滤器的步骤:
- 在 python 文件中 写好过滤器函数
- 使用装饰器
template_filter(name)装饰该过滤器函数,将该函数添加到全局
@app.template_filter(name='cut_hello') # name 就作为自定义过滤器的名称,在模版中使用
def cut_hello(value):
value = value.replace('hello', '')
return value
案例:自定义一个时间过滤器,用来统计文章发布的时间
# 自定义的创建时间的过滤器
@app.template_filter('cacl_time')
def cacl_create_time(time):
"""
计算距离现在的时间间隔
:param time: 发表时的时间
:return: 发表时间距离现在的时间
如果时间小于一分钟,就显示'刚刚'
如果时间大于1分钟小于60分钟 显示 'xx分钟前'
如果时间大于1小时小于24小时 显示 'xx小时前'
如果时间大于1天小于30天 显示 'xx天前'
否则显示 'x年x月x日'
"""
if isinstance(time, datetime):
now = datetime.now()
t = (now - time).total_seconds() # 获取间隔的秒数
print(t)
if t <= 60:
return '刚刚'
elif 60 < t <= 60 * 60:
return "{}分钟前".format(int(t / 60))
elif 60 * 60 < t <= 3600 * 24:
return "{}小前".format(int(t / (60 * 60)))
elif 60 * 60 * 24 < t <= 60 * 60 * 24 * 30:
return "{}天前".format(int(t / (3600 * 24)))
elif 60 * 60 * 24 * 30 < t <= 60 * 60 * 24 * 30 * 12:
return "{}月前".format(int(t / (60 * 60 * 24 * 30)))
else:
return time.strftime('%Y/%m/%d')
return time
流程控制语句
所有的流程控制语句都必须放在
{% %}中,并且还有 end 语句
if条件语句
- 格式:
{% if xxx %}
语句块
{% else %}
语句块
{% endif %}
- 与
python类似,可以使用and,or,not,()等逻辑进行操作。
for 、for in 循环语句
- 格式:
{% for 变量 in 可迭代对象 %}
代码块
{% endfor %}
- 使用方式和
python一样,并且jinjan2中的for循环包括以下变量,可以用来获取当前的遍历状态:
| 变量 | 描述 |
|---|---|
loop.index |
当前迭代的索引(从 1 开始) |
loop.index0 |
当前迭代的索引(从 0 开始) |
loop.first |
是否是第一次迭代,返回 True 或者 False
|
loop.last |
是否是最后一次迭代,返回 True 或者 False
|
loop.length |
序列的长度 |
-
注意 不可使用
continue和break来控制循环的执行 -
可以和
else一起使用
宏 与 inclue语句
宏
模版中的宏跟python中的函数类似,可以传递参数,但是不能有返回值,可以将一些经常使用到的代码片段放到宏中,然后把一些不固定的值抽出来当成一个变量,以下通过一个例子来说明:
-
定义宏
{% macro input(name, value='',type='text') %} <input type="{{ type }}" name="{{ name }}" value="{{ value | e }}"> {% endmacro %} -
使用宏
用户名:{{ input('username') }} 密码:{{ input(name='password',type='password') }} {{ input(name='', value="提交", type='submit') }} -
导入宏
在开发中,常常把一些常用的宏单独放在一个文件中,在需要的时候再倒入。
import语句用法跟python中类似,可以直接使用import ... as ...
也可以使用from ... import ... [ as ...],
例如在macros.html文件夹下,有 宏input,那么导入它的形式可以如下:{# 注意:from 之后跟 文件名字符串 ,默认从项目模版文件路径下算起 #} {% from 'macros.html' import input %}或者
{% import 'macros.html' as maros %}这种方式,使用需要用
maros.xxx格式。注意:
-
宏文件的路径都是从模版路径算起的。
-
在导入宏时,如果 需要红的定义需要使用后台传递的参数,
那么在导入宏的时候可以 添加with context
-
inclue语句
inclue语句是可以把加载一些 公用的模版,
直接把 文件 粘贴到 导入的地方
-
使用方式
include 模版文件路径(从项目指定的模版文件算起) -
如果需要使用父模板中的变量,直接使用,不需要 添加
with context
set、with 语句
在模版中, 可以使用set语句来定义变量。示例如下:
{% set username = 'ck' %}
一旦定义了这个变量,那么在后面的代码中,都可以使用这个变量,
类似于 python 中的变量定义。
如果需要限制范围,可以用with语句,如下:
{% with username = 'ck' %}
用户名:{{ username }}
{% endwith %}
或者
{% with %}
{% set username = 'ck' %}
用户名:{{ username }}
{% endwith %}
范围在 with与endwith之间
加载 静态文件
在模版文件中使用 url_for('static',filename='文件的路径')
例如,加载一个css文件
{{ url_for('static',filename='css/index.css') }}">
注意:filename是从 项目静态文件夹算起的
模版继承
-
为什么要使用模版继承
模版继承可以把一些公用的代码单独抽取出来放到一个父模板中,以后子模板只要继承就可以使用了。这样可以减少重复性的代码。 -
模版继承的语法
使用extends语句,来指明继承的父模板。父模板的路径也是templates下的绝对路径,示例代码如下:
{% extends 'base.html'%}
-
block语法
一般在父模板中,定义一些公用的代码。子模板中可能更具不同的需求实现不同的功能
这时候父模板可以提供一个接口,让子模板实现,从而实现不同的业务需求。在父模板中:
{% block block_name %} {% endblock %}在子模板中:
{% block block_name %} 子模板中代码的实现 {% endblock %} -
调用父模板中 block 的代码
默认情况下,子模板实现了父模板中的代码,那么子模板就会覆盖掉父模板中的代码,
如果还不需要覆盖父模板中的代码,那么可以使用{{ super() }}来调用父模板中的代码
,示例如下:父模板中:
{% block content %} <p style="background-color: azure">这是父模板中 block中的代码</p> {% endblock %}子模板中:
{% block content %} <p style="background-color: cadetblue">这是子模板中 block中的代码</p> {% endblock %} -
调用另一个 block 的代码
如果需要在模板中调用另外一个block中的代码,那么可以使用{{ self.其他模版的名字() }}来调用
,示例代码如下:{% block title %} flask jinja2 模版继承 {% endblock %} {% block content %} {{ self.title() }} <p style="background-color: cadetblue">这是子模板中 block中的代码</p> {% endblock %} -
其他注意事项
- 子模板中的第一行代码,应该是继承的代码
- 子模板中放在了
block外的代码,不会被渲染









网友评论