- 使用模板
- 使用方法
- 变量
- 过滤器
- 字符串过滤器
- 列表过滤器
- 自定义过滤器
- 表单
- WTForms支持的HTML标准字段
- WTForms常用的验证函数
- 表单的实际使用
- 控制语句
- if语句
- for语句
- 宏
- 不带参数的宏
- 带参数的宏
- 将宏封装在HTML文件中
- 模板的继承和包含
- 模板继承
- 模板包含
- Flask模板中的特殊变量和方法
- config对象
- request对象
- url_for()方法
- get_flashed_messages()方法
在Flask中使用render_template进行模板渲染
from flask import Flask, render_template
@app.route('/index')
def index():
return render_template('index.html', name='lisi', age=18)
注:在Flask中向模板中传递变量时,不能使用字典,而是要使用 变量名=值 的方式;如需使用字典,需要使用 **dict 的方式进行解包
变量Flask中,在模板中使用变量的方式和Django相同,都是采用 {{ 变量名 }} 的方式
对于字典,可以使用 {{ my_dict['key'] }} 或者 {{ my_dict.key }} 的方式获取值
对于列表,可以使用 {{ my_list[index] }} 的方式获取值
同时,在模板中可以直接进行运算和字符串的拼接
@app.route('/index')
def index():
data = {
'name': 'lisi',
'age': 18,
'my_dict': {'city': 'beijing'},
'my_list': [1, 2, 3, 4, 5],
'my_int': 0
}
return render_template('index.html', **data)
对应的模板内容为:
过滤器name = {{ name }}
age = {{ age }}
my_dict: city = {{ my_dict }}
my_dict: city = {{ my_dict['city'] }}
my_dict: city = {{ my_dict.city }}
my_list: {{ my_list }}
my_list[{{ my_int }}]: {{ my_list[my_int] }}
my_list[0] + my_list[1] = {{ my_list[0] + my_list[1] }}
{{ 'hel' + 'lo world' }}
Flask中的过滤器使用方式如下,同时还支持链式使用:
字符串过滤器a{{ ' flask world '|trim }}a
a{{ ' flask world '|trim|upper }}a
1> safe:禁用转义
2> capitalize:把变量值的首字母转成大写,其余字母转小写
3> lower:把值转成小写
4> upper:把值转成大写
5> title:把值中的每个单词的首字母都转成大写
6> trim:把值的首尾空格去掉
7> reverse:字符串反转,
{{ 'olleh' | reverse }}
8> format:格式化输出,
{{ '%s is %d' | format('name', 17) }}
9> striptags:渲染之前把值中所有的HTML标签都删掉 列表过滤器
1> first:取第一个元素
2> last:取最后一个元素
3> length:获取列表长度
4> sum:列表求和
5> sort:列表排序
自定义的过滤器名称如果和内置的过滤器重名,会覆盖内置的过滤器
- 方法一:使用函数:app.add_template_filter(过滤器函数名, 模板中使用的过滤器名字)
def list_step_2(li): return li[::2] # 注册过滤器,将自定义的过滤器添加到应用中 app.add_template_filter(list_step_2, 'li2') - 方法二:使用装饰器:app.template_filter(模板中使用的装饰器名字)
@app.template_filter('li3') def list_step_3(li): return li[::3] - 使用自定义的过滤器
{{ my_list|li2 }}
{{ my_list|li3 }}
在 Flask 中,为了处理表单,一般会使用 Flask-WTF 扩展,它封装了 WTForms,并且它有验证表单数据、快速定义表单模板、进行CSRF验证的功能
使用Flask-WTF需要配置参数SECRET_KEY
CSRF_ENABLED是为了CSRF(跨站请求伪造)保护,SECRET_KEY用来生成加密令牌,当 CSRF 激活的时候,该设置会根据设置的密匙生成加密令牌
安装:pip install Flask-WTF
| 字段对象 | 说明 |
|---|---|
| StringField | 文本字段 |
| TextAreaField | 多行文本字段 |
| PasswordField | 密码文本字段 |
| HiddenField | 隐藏文本字段 |
| DateField | 文本字段,值为datetime.date格式 |
| DateTimeField | 文本字段,值为datetime.datetime格式 |
| IntegerField | 文本字段,值为整数 |
| DecimalField | 文本字段,值为decimal.Decimal |
| FloatField | 文本字段,值为浮点数 |
| BooleanField | 复选框,值为True和False |
| RadioField | 一组单选框 |
| SelectField | 下拉列表 |
| SelectMultipleField | 下拉列表,可选择多个值 |
| FileField | 文本上传字段 |
| SubmitField | 表单提交按钮 |
| FormField | 把表单作为字段嵌入另一个表单 |
| FieldList | 一组指定类型的字段 |
| 验证函数 | 说明 |
|---|---|
| DataRequired | 确保字段中有数据 |
| EqualTo | 比较两个字段的值,常用于比较两次密码输入 |
| Length | 验证输入的字符串长度 |
| NumberRange | 验证输入的值在数字范围内 |
| URL | 验证URL |
| AnyOf | 验证输入值在可选列表中 |
| NoneOf | 验证输入值不在可选列表中 |
视图函数如下:
from flask import Flask, render_template, redirect, url_for, session
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, EqualTo
app = Flask(__name__)
# 添加SECRET_KEY
app.config['SECRET_KEY'] = 'aldksf98asd76'
# 定义表单的模型类
class RegisterForm(FlaskForm):
# label:说明文字;validators:验证器,列表
username = StringField(label='用户名', validators=[DataRequired('用户名不能为空')])
password = PasswordField(label='密码', validators=[DataRequired('密码不能为空')])
password2 = PasswordField(label='确认密码', validators=[DataRequired('确认密码不能为空'), EqualTo('password', '两次密码不一致')])
submit = SubmitField(label='提交')
@app.route('/register', methods=['GET', 'POST'])
def register():
# 创建表单模型类的对象,
# 如果是post请求,前端发送的数据,flask会在构造form对象的时候,将数据自动存放到form对象中
form = RegisterForm()
# 判断form中的数据是否合理,数据全部合理则返回True,否则返回False
if form.validate_on_submit():
# 表示验证合格,提取数据
uname = form.username.data
pwd = form.password.data
pwd2 = form.password2.data
print(uname, pwd, pwd2)
session['username'] = uname
return redirect(url_for('index'))
return render_template('register.html', form=form)
@app.route('/index')
def index():
username = session['username']
return 'hello %s' % username
if __name__ == '__main__':
app.run(debug=True)
模板内容如下:
控制语句 if语句{% if %}
{% endif %}
for语句
{% for item in samples %}
{% endfor %}
宏
类似于 Python 中的函数,宏的作用就是在模板中重复利用代码,避免代码冗余
不带参数的宏
{% macro input() %}
{% endmacro %}
{{ input() }}
带参数的宏
{% macro input2(type, size, value='abc') %}
{% endmacro %}
{{ input2('password', 50) }}
将宏封装在HTML文件中
创建一个 HTML 文件 macro_input.html,里面可以只存放宏
{% macro input3(type, size, value='abc') %}
{% endmacro %}
从其他 HTML 文件中导入并使用宏
{% import 'macro_input.html' as m_input %}
{{ m_input.input3('text', 20) }}
模板的继承和包含
模板继承
Flask 中模板的继承和 Django 中是相同的。父模板中可以通过 {% block top %}{% endblock top %} 在模板中预留位置;子模板可以使用 extends 指令调用父模板,同时可以使用 super() 使用父模板中的内容
父模板:base.html
{% block top %}
{% endblock top %}
子模板:
{% extends 'base.html' %}
{% block top %}
需要填充的内容
{% endblock top %}
模板包含
模板包含的作用是将另一个模板整个加载到当前模板中,并直接渲染,使用如下:
{% include 'hello.html' %}
注:包含在使用时,如果包含的模板文件不存在时,程序会抛出 TemplateNotFound 异常,可以加上 ignore missing 关键字,如果包含的模板文件不存在,会忽略这条 include 语句,示例如下:
{% include 'hello.html' ignore missing %}
Flask模板中的特殊变量和方法
在 Flask 中,有一些特殊的变量和方法是可以在模板文件中直接访问的
config对象config 对象就是 Flask 的 config 对象,也就是 app.config 对象,可以在模板中直接访问
{{ config.SQLALCHEMY_DATABASE_URI }}
request对象
就是 Flask 中表示当前请求的 request 对象,request 对象中保存了一次 HTTP 请求的一切信息
| 属性 | 说明 | 类型 |
|---|---|---|
| data | 记录请求体中的数据,并转换为字符串 | * |
| form | 记录请求中的表单数据 | MultiDict |
| args | 记录请求中的查询参数 | MultiDict |
| cookies | 记录请求中的cookie信息 | Dict |
| headers | 记录请求中的报文头 | EnvironHeaders |
| method | 记录请求使用的HTTP方法 | GET/POST |
| url | 记录请求的URL地址 | string |
| files | 记录请求上传的文件 | * |
{{ request.url }}
url_for()方法
url_for()会返回传入的路由函数对应的 URL,所谓路由函数就是被app.route()路由装饰器装饰的函数。如果定义的路由函数是带有参数的,则可以将这些参数作为命名参数传入
{{ url_for('index') }}
{{ url_for('post', post_id=1024) }}
get_flashed_messages()方法
返回之前在 Flask 中通过 flash() 传入的信息列表。把字符串对象表示的消息加入到一个消息队列中,然后通过调用 get_flashed_messages() 方法取出
{% for message in get_flashed_messages() %}
{{ message }}
{% endfor %}
视图函数内容如下:
from flask import Flask, flash, render_template
app = Flask(__name__)
flag = True
# flash是存储在session中的,所以需要设置SECRET_KEY
app.config['SECRET_KEY'] = 'alkdd9a8s6d9898ad'
@app.route('/')
def index():
global flag
if flag:
flash('hello') # 添加闪现信息
flag = False
return render_template('flash.html')



