赞
踩
flask默认使用的模板引擎是jinja2,它是一个功能齐全的python模板引擎,除了设置变量,还允许我们添加if判断,执行for循环,调用函数等。以各种方式控制模板的输出。
对应jinja2来说,模板可以是任何格式的纯文本文件,比如HTML、XML、CSV等。
目录
变量名必须由字母、数字、下划线(不能以下划线开头)和点组成。
语法如下:
{{ var }}
你可以使用点( . )来访问变量的属性,作为替代,也可以使用所谓的“下标”语 法( [])。下面的几行效果是一样的:
- {{foo.bar }}
- {{ foo['bar'] }}
如果变量或属性不存在,会返回一个未定义值。
- def book_list(request):
- books = BookInfo.objects.all()
- context = {'books': books}
-
- return render(request, 'book_list.html', context)
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>图书列表</title>
- </head>
- <body>
- {{ books }}
- <br>
- {{ books.0 }}
- <br>
- {{ books.0.author }}
- </body>
- </html>
和其它语句一样,需要在for循环的结尾使用 {% endfor %} 标签声明for语句的结束。
- {% for row in rows %}
- <li class="{{ loop.cycle('odd', 'even') }}">{{ row }}</li>
- {% endfor %}
-
- loop.index
- loop.index0
- loop.reindex
- loop.reindex0
- loop.first
- loop.last
- loop.length
- loop.cycle
- loop.depth
- loop.depth0
- loop.previtem
- loop.nextitem
在for循环内,jinja2提供了多个特殊变量,
变量名 | 作用 |
loop.index | 当前迭代数,从1开始计数 |
loop.index() | 当前迭代数,从0开始计数 |
loop.revindex | 当前反向迭代数,从1开始计数 |
loop.revindex() | 当前反向迭代数,从0开始计数 |
loop.first | 如果是第一个元素则为True |
loop.last | 如果是最后一个元素则为True |
loop.previtem | 上一个迭代的条目 |
loop.nextitem | 下一个迭代的条目 |
loop.length | 序列中元素的数量 |
- <ul>
- {% for user in users %}
- <li>{{ user.username|e }}</li>
- {% else %}
- <li><em>no users found</em></li>
- {% endfor %}
- </ul>
- {% for user in users if not user.hidden %}
- <li>{{ user.username|e }}</li>
- {% endfor %}
- <ul class="sitemap">
- {%- for item in sitemap recursive %}
- <li><a href="{{ item.href|e }}">{{ item.title }}</a>
- {%- if item.children -%}
- <ul class="submenu">{{ loop(item.children) }}</ul>
- {%- endif %}</li>
- {%- endfor %}
- </ul>
loop的例子:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>{{ user.username }}'s watchlist</title>
- </head>
- <body>
- <a href="{{ url_for('hi') }}">← Return</a>
- <h2>{{ user.username}}</h2>
- {% if user.bio %}
- <i>{{ user.bio }}</i>
- {% else %}
- <i>This user has not provided a bio.</i>
- {% endif %}
- {# 以下是电影清单(这是注释) #}
- <h5>{{ user.username }}'s watchlist ({{ movies|length }}):</h5>
- <ul>
- {% for movie in movies %}
- <li>loop.index:{{ loop.index }} loop.first:{{ loop.first }}
- loop.last:{{ loop.last }} - {{ movie.name }} - {{ movie.year }}</li>
- {% endfor %}
- </ul>
- </body>
- </html>
浏览器访问:http://127.0.0.1:5000/watchlist
- {% if ... %}
-
- {% elif ... %}
-
- {% else %}
-
- {% endif %}
比较运算符如下:
- ==
- !=
- <
- >
- <=
- >=
布尔运算符如下:
- and
- or
- not
{{ #...#}}
- block
- {% block xxx %}
- pass
- {% endblock %}
-
- extends
- {% extends 'xxx' %}
- 续承后保留块中的内容
- {{ super() }}
-
- include
- {% include 'xxx' %}
- 包含,将其他HTML包含进来,体现的是由零到一的概念
-
- marco
- {% marco hello(name) %}
- {{ name }}
- {% endmarco %}
- 宏定义,可以在模块中定义函数,在其他地方调用
- 宏定义可以导入
- {% from 'xx' import xxx %}
jinja2通过了多种控制结构来控制模板的输出,其中for和if是最常用的2种。jinja2里,语句使用{undefined{%...%}}标识。需要注意的是,在语句结束的地方,必须添加结束标签,如:
- {% if user.bio %}
- <i>{{ user.bio }}</i>
- {% else %}
- <i>This user has not provided a bio.</i>
- {% endif %}
在这个if语句中,如果user.bio已经定义,就渲染{% if user.bio %}和{% else %}之间的内容,否则就渲染{% else %}和{% endif %}之间的内容。末尾的{% endif %}用来表示if语句的结束,不能省略。
您也可以手动去除模板中的空白。 如果加减号 符号 ( -
) 到块的开头或结尾(例如 For 标签),a 注释或变量表达式,之前或之后的空格 该块将被删除:
- {% for item in seq -%}
- {{ item }}
- {%- endfor %}
不得在标记和减号之间添加空格。
有效 :
{%- if foo -%}...{% endif %}
无效 :
{% - if foo - %}...{% endif %}
过滤器:本质上就是一个python语言定义的一个方法,但是在模板语言中不能直接调用python的方法,只能通过过滤器的方式来调用。
即python中定义方法,仍后将方法加入到过滤器列表中,加入后就可以在模板语言中进行调用。 而且模板语言支持链式调用,比如:{{"hello world" | reverse | upper }}
模板语言过滤器调用格式:{{variable | filter_func_name(*args)}}
没有参数时可以将参数括号省略如:{{variable | filter_func_name}}
链式调用:{{variable | filter_func_name1 | filter_func_name2}}
字符串操作
- safe:禁用转义
- <p>{{ '<em>hello</em>' | safe }}</p>
-
- capitalize:把变量值的首字母转成大写,其余字母转小写
- <p>{{ 'hello' | capitalize }}</p>
-
- lower:把值转成小写
- <p>{{ 'HELLO' | lower }}</p>
-
- upper:把值转成大写
- <p>{{ 'hello' | upper }}</p>
-
- title:把值中的每个单词的首字母都转成大写
- <p>{{ 'hello' | title }}</p>
-
- reverse:字符串反转
- <p>{{ 'olleh' | reverse }}</p>
-
- format:格式化输出
- <p>{{ '%s is %d' | format('name',17) }}</p>
-
- striptags:渲染之前把值中所有的HTML标签都删掉
- <p>{{ '<em>hello</em>' | striptags }}</p>
-
- truncate: 字符串截断
- <p>{{ 'hello every one' | truncate(9)}}</p>
列表操作:
- first:取第一个元素
- <p>{{ [1,2,3,4,5,6] | first }}</p>
- last:取最后一个元素
- <p>{{ [1,2,3,4,5,6] | last }}</p>
-
- length:获取列表长度
- <p>{{ [1,2,3,4,5,6] | length }}</p>
- sum:列表求和
- <p>{{ [1,2,3,4,5,6] | sum }}</p>
-
- sort:列表排序
- <p>{{ [6,2,3,1,5,4] | sort }}</p>
- 语句块过滤
- {% filter upper %}
- #一大堆文字#
- {% endfilter %}
自定义过滤器:
自定义过滤器有两种实现方式:
一种是通过Flask应用对象的 add_template_filter 方法
- def do_listreverse(li):
- # 通过原列表创建一个新列表
- temp_li = list(li)
- # 将新列表进行返转
- temp_li.reverse()
- return temp_li
-
- app.add_template_filter(do_listreverse,'lireverse')
- @app.template_filter('lireverse')
- def do_listreverse(li):
- # 通过原列表创建一个新列表
- temp_li = list(li)
- # 将新列表进行返转
- temp_li.reverse()
- return temp_li
在 html 中使用该自定义过滤器
- <br/> my_array 原内容:{{ my_array }}
- <br/> my_array 反转:{{ my_array | lireverse }}
运行结果
- my_array 原内容:[3, 4, 2, 1, 7, 9]
- my_array 反转:[9, 7, 1, 2, 4, 3]
Jinja2模板中,除了宏和继承,还支持一种代码重用的功能,叫包含(Include)。
功能是将另一个模板整个加载到当前模板中,并直接渲染。
{% include 'hello.html' %}
包含在使用时,如果包含的模板文件不存在时,程序会抛出TemplateNotFound异常,可以加上 ignore missing 关键字。如果包含的模板文件不存在,会忽略这条include语句。
{% include 'hello.html' ignore missing %}
对宏(macro)的理解:
把它看作 Jinja2 中的一个函数,它会返回一个模板或者 HTML 字符串。
为了避免反复地编写同样的模板代码,出现代码冗余,可以把他们写成函数以进行重用,需要在多处重复使用的模板代码片段可以写入单独的文件,再包含在所有模板中,以避免重复使用。
定义宏:
- {% macro input(name,value='',type='text') %}
- <input type="{{type}}" name="{{name}}"
- value="{{value}}" class="form-control">
- {% endmacro %}
调用宏:
{{ input('name' value='zs')}}
上面对于宏的调用,相当于输出
- <input type="text" name="name"
- value="zs" class="form-control">
把宏单独抽取出来,封装成html文件,其它模板中导入使用,文件名可以自定义macro.html
- {% macro input(label="", type="text", name="", value="") %}
- <label>{{ label }}</label>
- <input type="{{ type }}" name="{{ name }}"
- value="{{ value }}">
- {% endmacro %}
参考文档:Jinja模板语法官方文档
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。