什么是Jinja2?
Jinja2是基于python的模版引擎,它能完全支持unicode,并具有继承的沙箱执行环境。它的设计思想来源于Django的模版引擎,并扩展了其语法和一系列强大的功能。
默认情况下,Flask在程序文件夹中的templates子文件夹中寻找模版。
ununited.py
from flask import Flask,render_template
app=Flask(__name__)
@app.route("/<name>")
def hello(name):
if name=='westos':
return render_template('index.html',name=name)
else:
return render_template('index.html',name='world')
if __name__=="__main__":
app.run(host='0.0.0.0',port=9000)
index.html
<h1>Hello,world</h1><br>
<h2>Hello,{{ name }}</h2>
运行结果:终端输出
* Running on http://0.0.0.0:9000/ (Press CTRL+C to quit)
在浏览器的地址栏输入
http://0.0.0.0:9000/westos
render_template()函数
在上面的程序中,使用了Flask提供的render_template函数,该函数把Jinja2模版引擎集成到了程序中。render_template函数的第一个参数是模版的文件名。随后的参数都是键值对。表示模版中的变量对应的真实值。
变量
Jinja模版使用{{变量名}} 表示一个变量,它告诉模版引擎这个位置的值从渲染模版时使用的数据中获取。还能使用列表,字典和对象等复杂的类型。
如:
<p>Hello,{{mydict['key']}}.Hello,{{mylist[0]}}.</p>
控制结构
Jinja提供了多种控制结构来改变模版的渲染流程。比如常见的判断结构,循环结构。
宏
Jinja2里面的宏相当于python里面的函数。
定义一个宏
macro.html
{#定义一个关于创建表单的宏#}
{#macro 是定义宏的关键字相当于python里面的def,在定义的宏的结尾还要加上{% endmacro %}#}
{% macro input(name,type='text',value='') %}
<input type="{{ type }}" name="{{ name }}" value="{{ value }}">
{% endmacro %}
enroll.html
<form>
{# 调用定义的宏#}
{% from 'macro.html' import input %}
用户名{{ input(name="name") }}<br>
密码{{ input(name="passwd",type="password") }}<br>
注册{{ input(type="submit",value="注册") }}
</form>
继承
另一种重复使用代码的强大方式是模版继承,就像类继承一样需要一个基类,这里也需要一个基模版。
base.html
<!DOCTYPE html>
<html lang="en">
<head>
{% block head%}
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
{% endblock%}
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>
继承模版
{#继承哪个模版 关键字extends#}
{% extends "model.html" %}
{% block title %}
index
{% endblock %}
{% block head %}
{{ super()}}
{%endblock%}
{% block body %}
<h1>hello world</h1>
{% endblock %}
继承之后重新定义title、head、body,使用super()获取基模版原来的内容。
变量显示
from flask import Flask,render_template
app = Flask(__name__)
class User(object):
def __init__(self,name,passwd):
self.name=name
self.passwd=passwd
def __str__(self):
return '<User: %s' %(self.name)
@app.route('/')
def hello_world():
name='westos'
li=[1,2,3,4]
d=dict(a=1,b=3,c=6)
u=User('root','redhat')
return render_template('index.html',
li=li,
d=d,
u=u )
if __name__ == '__main__':
app.run()
index.html
<h3>字符串变量显示</h3>
{{ name }}
<h3>列表</h3>
{{ li }}
<h3>字典</h3>
{{ d }}
<table border="1px" width="30%">
{% for i in d %}
{% if i in ['a','c'] %}
<tr>
<td>{{ i }}</td>
<td>{{ d[i] }}</td>
</tr>
{% else %}
<tr>
<td>{{ i }}</td>
<td>{{ d[i] }}</td>
</tr>
{% endif %}
{% endfor %}
</table>
<h3>对象</h3>
{{ u }}
<table border="1px">
<tr>
<td>用户名</td>
<td>密码</td>
</tr>
<tr>
<td>{{ u.name }}</td>
<td>{{ u.passwd}}</td>
</tr>
</table>
过滤器
用来在变量被使用或者显示前,对其做转换处理的。可以认为是一种转换函数,输入的参数就是其所修饰的变量,返回的就是变量转换后的值。
将变量传给前端
from flask import Flask, render_template
app = Flask(__name__)
class User(object):
def __init__(self, name, passwd):
self.name = name
self.passwd = passwd
def __str__(self):
return '<User: %s>' % (self.name)
# 视图函数
@app.route('/')
def index():
name = 'westoswestosexam'
li = [1, 2, 3, 4]
d = dict(a=1, b=3, c=6)
u = User('root', 'redhat')
a = [
{'name': 'apple', 'count': 10},
{'name': 'banada', 'count': 20},
]
return render_template('index2.html',
name=name,
li=li,
d=d,
u=u,
a=a)
#自定义一个过滤器
def sub(l, start, end):
return l[::-1]
app.add_template_filter(sub, 'sub')
if __name__ == "__main__":
# 运行web app
app.run(host='0.0.0.0', port=9009)
index2.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
<h3>字符串变量显示</h3>
{{ name }}
<!--常见的字符串的过滤器
- 过滤器实质上就是一个转换函数/方法;
-->
<p style="color: red"> {{ name | upper }}</p>
<p style="color: red"> {{ name | lower }}</p>
<p style="color: red"> {{ name | capitalize }}</p>
<p style="color: red"> {{ " hello " }}</p>
<!--<p style="color: red"> {{ " hello " | trim }}</p>-->
<!--反转字符串-->
<p style="color: red"> {{ name | reverse }}</p>
<!--<p style="color: red"> {{ name | truncate(3, False) }}</p>-->
<!--数值置的过滤器操作-->
<!--四舍五入取整-->
<p style="color: green"> {{ 12.164 | round }}</p>
<p style="color: green"> {{ 12.164345435 | round(3, 'floor') }}</p>
<p style="color: green"> {{ -12.164345435 | abs }}</p>
<h3>列表</h3>
{{ li }}
<p style="color: aqua">{{ li | first }}</p>
<p style="color: aqua">{{ li | last }}</p>
<p style="color: aqua">{{ li | length }}</p>
<p style="color: aqua">{{ li | sum }}</p>
<p style="color: aqua">{{ li | sort }}</p>
<p style="color: aqua">{{ li | sort | reverse }}</p>
<p style="color: aqua">{{ li | join(', ') }}</p>
<p style="color: aqua">{{ ['hello', 'worlD'] | upper }}</p>
<p style="color: aqua">{{ ['hello', 'worlD'] | lower }}</p>
<p style="color: aqua">{{ li | sub(2,4) }}</p>
<h3>字典</h3>
{{ d }}
<!--jinja2的for循环-->
<table border="1px" width="80%">
{% for i in d %}
{% if i in ['a', 'c'] %}
<tr style="background-color: lightgray">
<td>{{ i }}</td>
<td>{{ d[i]}}</td>
</tr>
{% else %}
<tr style="background-color: lightpink">
<td>{{ i }}</td>
<td>{{ d[i]}}</td>
</tr>
{% endif %}
{% endfor %}
</table>
<!--列表嵌套字典的内值过滤器-->
{% for i in a | sort(attribute='count', reverse=true)%}
{{i.name}}
{{i.count}}
{% endfor %}
<h3>对象</h3>
{{ u }}
<table border="1px">
<tr>
<td>用户名</td>
<td>密码</td>
</tr>
<tr>
<td>{{ u.name }}</td>
<td>{{ u.passwd }}</td>
</tr>
</table>
</body>
</html>