黄色标注部分重点注意
宏和模板控制语句
1. 模板控制语句
•所有的控制语句都是放在{% … %}
中,并且由一个语句{% endxxx %}
来结束,Jinja中常用的控制语句有if
、
for…in…
等
if判断语句
•flask中的if语句和Python中类似,可以使用>、<、<=、>=、和!=
来进行判断,也可以通过and、or、not、()
来进行逻辑合并==操作
{% if weather == 'sunny' %}
<p>出去写代码</p>
{% elif weather == 'rainy' %}
<p>在家写代码</p>
{% else %}
<p>出去玩</p>
{% endif %}
if判断语句运行测试:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/ycx/')
def checkout():
context = {
'name': 'ycx'
}
return render_template('checkout.html', **context)
if __name__ == '__main__':
app.run(debug=True, port=8000)
模板代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>if控制语句</title>
</head>
<body>
<h3>{{ name }}</h3>
{% if name=='jerry' %}
<p>{{ name }}</p>
{% else %}
<p>此用户不存在!!</p>
{% endif %}
</body>
</html>
网页显示:
for循环语句
•for循环可以遍历任何一个序列包括列表、字典、元组
,并且可以进行反向遍历
for循环遍历列表和字典运行测试:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/ycx/')
def checkout():
context = {
'name': 'ycx',
'languages': ['python', 'java', 'php', 'c++'],
'player': {
'name': '十一',
'age': 18,
'major': 'knight'
}
}
return render_template('checkout.html', **context)
if __name__ == '__main__':
app.run(debug=True, port=8000)
模板代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>if控制语句</title>
</head>
<body>
<h3>{{ name }}</h3>
{% for language in languages %}
<p>{{ language }}</p>
{% endfor %}
<hr>
{% for key,value in player.items() %}
<p>{{ key }}:{{ value }}</p>
{% endfor %}
</body>
</html>
网页显示:
else语句
可以在序列为空时退出for循环,测试如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>if控制语句</title>
</head>
<body>
<h3>{{ name }}</h3>
{% for subject in subjects %}
<p>{{subject}}</p>
{% else %}
<em>没有学科需要学习!!!</em>
{% endfor %}
</body>
</html>
网页显示:
Jinja中的for循环还可以包含变量以用来获取当前的遍历状态,常见变量如下:
变量 | 描述信息 |
---|---|
loop.index | 当前迭代的索引(从1开始) |
loop.index0 | 当前迭代的索引(从0开始) |
loop.first | 是否是第一次迭代,返回True或False |
loop.last | 是否是最后一次迭代,返回True或False |
loop.length | 序列的长度 |
获取当前遍历状态测试:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/ycx/')
def checkout():
context = {
'name': 'ycx',
'languages': ['python', 'java', 'php']
}
return render_template('checkout.html', **context)
if __name__ == '__main__':
app.run(debug=True, port=8000)
模板代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>if控制语句</title>
</head>
<body>
<h3>{{ name }}</h3>
{% for language in languages %}
<p>{{ loop.index}}-----{{ language }}</p>
{% endfor %}
<hr>
{% for language in languages %}
<p>{{ loop.index0}}-----{{ language }}</p>
{% endfor %}
<hr>
{% for language in languages %}
<p>{{ loop.first}}-----{{ language }}</p>
{% endfor %}
<hr>
{% for language in languages %}
<p>{{ loop.last}}-----{{ language }}</p>
{% endfor %}
</body>
</html>
网页显示:
注意事项:
不能使用continue和break表达式来控制循环的执行,它们在模板中是无效的
2. 宏和import语句
宏的定义和使用
•模板中的宏跟python中的函数类似,可以传递参数,但是没有返回值,可以将一些常用的代码片段放到宏中,然后把一些不固定的值抽取出来作为参数,可供再次使用
宏定义的语法:
{% macro 宏名字(参数) %}
常用代码片段
{% endmacro %}
运行测试:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/macro/')
def macro():
return render_template('macro.html')
if __name__ == '__main__':
app.run(debug=True, port=8000)
新建模板macro.html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>宏定义模块</title>
</head>
<body>
{% macro input(name, value='', type='text') %}
<input name="{{name}}" value="{{value}}" type="{{type}}">
{% endmacro %}
<table>
<tr>
<td>用户名:</td>
<td>{{input('username')}}</td>
</tr>
<tr>
<td>密码:</td>
<td>{{input('password', type='password')}}</td>
</tr>
<tr>
<td>提交</td>
<td>{{input(value='提交', type='submit')}}</td>
</tr>
</table>
</body>
</html>
网页显示:
定义的宏抽取出了一个input标签,指定了一些默认参数,创建input标签的时候,就可以通过宏快速的创建
{% macro input(name, value=’’, type=‘text’) %}
定义了一个类似于函数的结构,传入参数就可以生成对应的模板直接使用
import语句
•在实际开发中,会将一些常用的宏单独放在一个文件中,在需要使用的时候,再从这个文件中进行导入
•import语句的用法跟python中的import类似,可以直接import…as…
,也可以from…import…
或者from…import…as…
导入所需要的宏或者模块
macro.html文件用于专门保存抽取出来的宏:
运行测试:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/macro/')
def macro():
context = {
'username': 'ycx'
}
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True, port=8000)
macro.html文件:
{% macro input(name, value='', type='text') %}
<input name="{{name}}" value="{{value}}" type="{{type}}">
{% endmacro %}
新建模板文件index.html:
{% import 'macro.html' as macro %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask</title>
</head>
<body>
<h1>首页</h1>
<h2>{{username}}</h2>
<hr>
请输入:{{ macro.input('username') }}
</body>
</html>
网页显示:
访问主页时,渲染导入的宏并生成输入框
可以用from xxx import xxx
语句导入自己所需要的宏,如下:
{% from 'macro.html' import input %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask</title>
</head>
<body>
<p>请输入用户名:{{ input('username') }}</p>
<p>请输入密码:{{ input('password', type='password') }}</p>
</body>
</html>
网页显示:
这种导入方式还可以给宏重命名,例如:from ‘macro.html’ import input as xxx
3. include和set语句
include语句
•include语句
可以把一个模板引入到另外一个模板中,类似于把一个模板的代码copy到另外一个模板的指定位置
•测试过程如下:
先在templates目录下创建file文件夹,再在file文件夹下创建header.html和footer.html文件
header.html文件如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Header</title>
</head>
<body>
<ul>
<li>军事</li>
<li>科技</li>
<li>财经</li>
<li>娱乐</li>
</ul>
</body>
</html>
footer.html:
<footer>
这是页面底部
</footer>
在templates
目录下创建article.html文件
,如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Article</title>
</head>
<body>
{% include 'file/header.html' %}
<ul>
<li>第一篇文章</li>
<li>第二篇文章</li>
<li>第三篇文章</li>
</ul>
{% include 'file/footer.html' %}
</body>
</html>
视图函数如下:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def checkout():
return render_template('checkout.html')
if __name__ == '__main__':
app.run(debug=True)
网页显示:
set语句
•一般情况下是在视图函数中定义变量、在模板中引用,但是也可以在模板中直接添加变量,这时候就会用到set赋值语句
测试如下:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def checkout():
context = {
'name': 'ycx'
}
return render_template('checkout.html',**context)
if __name__ == '__main__':
app.run(debug=True)
模板文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Article</title>
</head>
<body>
{% set username='小爱同学' %}
<p>{{ name }}</p>
<p>{{ username }}</p>
</body>
</html>
网页显示:
在视图函数中未定义name变量时,模板可以渲染set定义的name变量,视图函数中定义了name变量时会覆盖视图函数中的值
通过set定义全局变量一次只能定义一个,并且赋值语句创建的变量在其之后都是有效的
•如果不想让一个变量影响到全局环境,可以使用with语句来创建一个内部的作用域,将set语句放在其中,这样创建的变量只在with代码块中才有效,即相当于创建了一个局部变量
代码测试:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Article</title>
</head>
<body>
{% set username='小爱同学' %}
<p>{{ name }}</p>
<p>{{ username }}</p>
{% with %}
{% set name='天猫精灵' %}
<p>{{ name }}</p>
{% endwith %}
</body>
</html>
网页显示:
超出with代码块,在该代码块中定义的局部变量就失效了
定义字典和列表并遍历:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Article</title>
</head>
<body>
{% set username='小爱同学' %}
<p>{{ name }}</p>
<p>{{ username }}</p>
{% with %}
{% set name='天猫精灵' %}
<p>{{ name }}</p>
{% endwith %}
<hr>
{% with dict = {'name':'小爱同学', 'country':'China'} %}
<p>{{ dict.name }}</p>
<p>{{ dict.country }}</p>
{% endwith %}
<hr>
{% with list = ['十一', '初三', '周九'] %}
{% for item in list %}
<p>{{ item }}</p>
{% endfor %}
{% endwith %}
</body>
</html>
网页显示: