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
外的代码,不会被渲染
网友评论