使用flask.render_template函数封装jinja2模板引擎.
在项目中创建templates文件夹
在pycharm中使用模板,IDE会报找不到警告
需要修改pycharm的设置,修改模板语言
变量:{{ 变量 }}
判断语句: {%if 表达式%} 语句1 {%elif 表达式%} 语句2 {{%else%}} 语句3 {% endif %}
循环语句: {% for foo in list_data %} 拿到数据:{{ foo }} {% endfor %}
注释语法: {# 注释 #}
Flask的视图代码:
# !/usr/bin python
# conding=utf-8
# 导入render_template模块
from flask import Flask, render_template
app = Flask(__name__)
# 使用模板加载index.html文件
@app.route("/")
def index():
# 定义模板数据
str = "测试一下中文的显示情况"
dict_data = {"name":"张三", "age":18}
list_data = [4,5,8,3,25,12]
return render_template("index.html",
str = str,
dict_data = dict_data,
list_data = list_data)
if __name__ == '__main__':
app.run(debug=True)
html模板文件
...
传字符串:{{ str }}
传字典:{{ dict_data }}
name: {{ dict_data["name"] }}
age:{{ dict_data['age'] }}
传入列表: {{ list_data }}
遍历列表:
{% for i in list_data %}
- {{ i }}
{% endfor %}
...
控制代码块主要包含两个:
Jinja2 语法中的if语句跟 Python 中的 if 语句相似,后面的布尔值或返回布尔值的表达式将决定代码中的哪个流程会被执行:
{%if user.is_logged_in() %}
Logout
{% else %}
Login
{% endif %}
过滤器可以被用在 if 语句中:
{% if comments | length > 0 %}
There are {{ comments | length }} comments
{% else %}
There are no comments
{% endif %}
我们可以在 Jinja2 中使用循环来迭代任何列表或者生成器函数
{% for post in posts %}
{{ post.title }}
{{ post.text | safe }}
{% endfor %}
循环和if语句可以组合使用,以模拟 Python 循环中的 continue 功能,下面这个循环将只会渲染post.text不为None的那些post:
{% for post in posts if post.text %}
{{ post.title }}
{{ post.text | safe }}
{% endfor %}
变量 | 描述 |
loop.index | 当前循环迭代的次数(从1开始) |
loop.index0 | 当前迭代的次数(从0开始) |
loop.revindex | 到循环结束需要迭代的次数(从1开始) |
loop.revindex0 | 到循环结束需要迭代的次数(从0开始) |
loop.first | 判断循环是否为第一次迭代/td> |
loop.last | 判断循环是否为最后一次循环 |
loop.length | 序列中的项目数 |
loop.cycle/td> | 在一串序列间取值的辅助函数 |
在循环内部,你可以使用一个叫做loop的特殊变量来获得关于for循环的一些信息:
比如:要是我们想知道当前被迭代的元素序号,并模拟Python中的enumerate函数做的事情,则可以使用loop变量的index属性,例如:
{% for post in posts%}
{{loop.index}}, {{post.title}}
{% endfor %}
会输出这样的结果
1, Post title
2, Second Post
cycle函数会在每次循环的时候,返回其参数中的下一个元素,可以拿上面的例子来说明:
{% for post in posts%}
{{loop.cycle('odd','even')}} {{post.title}}
{% endfor %}
会输出这样的结果:
odd Post Title
even Second Post
flask视图代码:
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
my_list = [
{
"id":1,
"name":"张三",
"age": 18
},
{
"id": 2,
"name": "李四",
"age": 25
},
{
"id": 3,
"name": "王五",
"age": 16
},
]
return render_template("demo04.html", my_list = my_list)
if __name__ == '__main__':
app.run(debug=True)
模板代码:
模板的基本控制语句
{% for ls in my_list %}
{% if loop.index0 == 0 %}
{{ ls.name }}
{% elif loop.index0 == 1 %}
{{ ls.name }}
{% elif loop.index0 == 2 %}
{{ ls.name }}
{% endif %}
{% endfor %}
{{ 变量|过滤器 }}
...
{# 过滤器对字符串的处理 #}
当前字符串: {{ "bAnK OF cHiNA" }}
字符串反转: {{ "bAnK OF cHiNA" | reverse}}
{# 多个过滤器可以连用 #}
字符串首字母大写再反转: {{ "bAnK OF cHiNA" | capitalize |reverse }}
首字母大写:{{ "bAnK OF cHiNA" | capitalize }}
全部大写: {{ "bAnK OF cHiNA" | upper }}
全部小写:{{ "bAnK OF cHiNA" | lower }}
{# 模板默认情况下,会开启转义,把html标签当成原始字符串进行输出,所以模板不能识别html标签 #}
斜体默认输出:{{ "bAnK OF cHiNA" }}
斜体使用sate:{{ "bAnK OF cHiNA" | safe }}
...
...
{# 过滤器对列表的处理 #}
默认列表输出:{{ [4,2,3,1,5] }}
列表first输出:{{ [4,2,3,1,5] | first }}
列表last输出:{{ [4,2,3,1,5] | last }}
列表sum输出:{{ [4,2,3,1,5] | sum }}
列表sort输出:{{ [4,2,3,1,5] | sort }}
列表length输出:{{ [4,2,3,1,5] | length }}
...
自定义过滤器在视图中实现;
如果和内置的过滤器重名,会覆盖内置的过滤器
模板代码:
...
{# 使用自定义装饰器 #}
列表默认输出:{{ [4,2,3,1,5] }}
列表反转输出:{{ [4,2,3,1,5] | list_filter }}
列表反转输出:{{ [4,2,3,1,5] | list_filter2 }}
...
Flask视图函数代码:
...
# 自定义过滤器:实现列表数据的反转
def list_filter(ls):
# 把接受的参数转换成列表
temp_list = list(ls)
temp_list.reverse()
return temp_list
# 方法一:添加自定义过滤器给模板
# 第一个参数表示自定义过滤器的函数名,第二个参数表示过滤器的名称,如果和内置过滤器重名,会覆盖内置过滤器
app.add_template_filter(list_filter, "list_filter")
...
...
# 方法二:以装饰器的形式实现自定义过滤器
@app.template_filter("list_filter2")
def list_filter2(ls):
# 把接受的参数转换成列表
temp_list = list(ls)
temp_list.reverse()
return temp_list
...
模板继承是为了重用模板中的公共内容。一般Web开发中,继承主要使用在网站的顶部菜单、底部。这些内容可以定义在父模板中,子模板直接继承,而不需要重复书写。
base.html
{% block title %}父模板{% endblock %}的样式
{% block top %}
这是基模板的头部实现
{% endblock %}
{% block body %}
这是基模板的内容实现
{% endblock %}
{% block footer %}
这是基模板的底部实现...
{% endblock %}
继承的模板.html
{% extends "base.html" %}
{% block title %}继承模板{% endblock %}
{% block top %}
这是新的继承模板的top
{% endblock%}
Flask视图函数:
#!/usr/bin/env python3
# coding=utf-8
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
return render_template("demo06_extends.html")
if __name__ == '__main__':
app.run(debug=True)
宏的定义:
{% macro func([参数列表]) %}
样式实现
{% endmacro %}
宏的调用:
{{ func([实参]) }}
导入宏:
{% import "外部宏的模板文件" as 模板文件别名 %}
内部定义、内部调用无参宏:
...
{# 定义宏 #}
{% macro func() %}
{% endmacro %}
{# 调用宏 #}
{{ func() }}
...
内部定义、内部调用有参宏:
...
{# 调用宏 #}
{{ func() }}
{# 定义带参数的宏函数 #}
{% macro func1(type1, type2, size) %}
{% endmacro %}
{# 调用宏 #}
{{ func1("password", "password", 20) }}
...
从外部引用宏文件.html
{% macro fun(type,size) %}
{% endmacro %}
引用宏的模板:
...
{# 导入宏 #}
{% import 'temp_macro.html' as f %}
{# 从导入的文件中调用宏 #}
{{ f.fun('text','20') }}
模板文件.html
{% include "base.html" %}
这种写法没有做"文件不存在忽略"的处理,如果包含的文件不存在,jinja2引擎报错:
加入忽略包含的文件不存在参数,
{% include "base222.html" ignore missing %}
jinja2引擎不会报错,包含的内容为空,且响应码正确