Flask - 表单使用
- 可以根据视图函数名构造对应的路由地址
- 带参的路由也可以构造,多出来的参数会自动作为 get 参数
- 构造完整(带主机和端口)路由需要制定参数
_external=True
创建目录
1
2
3
4
5
6
7
8project/
manage.py # 启动控制文件
static/ # 静态文件
favicon.ico # 收藏夹图标
image/ # 存放图片
css/ # 存放css文件
js/ # 存放js文件
templates/ # 模板文件加载收藏夹图标
1
2
3
4
5{% block head %}
{{ super() }}
{# 加载收藏夹图标 #}
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='favicon.ico') }}">
{% endblock %}加载图片文件
1
<img src="{{ url_for('static', filename='image/meinv.jpg') }}" alt="美女">
加载 CSS 文件
1
2
3
4{% block styles %}
{{ super() }}
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/common.css') }}">
{% endblock %}加载 JS 文件
1
2
3
4{% block scripts %}
{{ super() }}
<script type="text/javascript" src="{{ url_for('static', filename='js/common.js') }}"></script>
{% endblock %}
模板文件
1
2
3
4
5<form method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="立即登录">
</form>添加登陆的视图函数
1
2
3
4
5
6
def login():
if request.method == 'GET':
return render_template('login.html')
else:
return request.form['username']
说明:提供了简洁的书写形式,提供了 CSRF(跨站请求伪造保护),提供了字段的校验等。
安装:
pip install flask-wtf
使用:
创建一个表单类
1
2
3
4
5
6
7
8
9
10
11
12
13# 导入表单基类
from flask_wtf import FlaskForm
# 导入需要的字段
from wtforms import StringField, SubmitField, PasswordField
# 设置秘钥,CSRF会使用
app.config['SECRET_KEY'] = '123456'
# 创建一个表单类
class NameForm(FlaskForm):
name = StringField('用户名:')
password = PasswordField('密码:')
submit = SubmitField('提交')视图函数中,创建一个表单对象,然后在渲染时分配到模板文件中
1
2
3
4
5
6
7
def index():
form = NameForm()
if request.method == 'GET':
return render_template('form.html', form=form)
else:
return form.name.data原生渲染,需要对表单中的每个字段单独渲染处理
1
2
3
4
5
6
7
8
9
10
11<form method="post" action="">
{# CSRF用途的隐藏字段 #}
{{ form.hidden_tag() }}
{# name字段 #}
{{ form.name.label() }}{{ form.name(id='xxx', class='yyy') }}<br>
{# password字段 #}
{{ form.password.label() }}{{ form.password() }}<br>
{# 登录字段 #}
{{ form.submit() }}
</form>
Bootstrap
进行渲染1
2
3
4
5
6
7
8
9
10
11
12
13{% extends 'bootstrap/base.html' %}
{% block title %}表单渲染{% endblock %}
{# 导入渲染工具 #}
{% import 'bootstrap/wtf.html' as wtf %}
{# 渲染表单 #}
{% block content %}
<div class="container">
{{ wtf.quick_form(form) }}
</div>
{% endblock %}验证器使用
需要导入相关的验证器类
1
2# 导入需要的验证器类
from wtforms.validators import Length在需要验证的字段后添加相关的验证器对象
1
name = StringField('用户名:', validators=[Length(6, 20, '必须在6-20个字符之间')])
表单提交的校验需要使用函数
validate_on_submit
1
2
3
4
5
6
7
8
def index():
name = None
form = NameForm()
# if request.method == 'POST':
if form.validate_on_submit():
name = form.name.data
return render_template('form2.html', form=form, name=name)
常见的字段类型
字段类型 说明 StringField 普通文本 SubmitField 提交按钮 PasswordField 密文字段 HiddenField 隐藏字段 TextAreaField 多行文本输入 IntegerField 整数 FloatField 浮点数 BooleanField 复选框 RadioField 单选框 SelectField 下拉框 FileField 上传文件 DateField 日期 DateTimeField 日期时间 常见的验证器
验证器 说明 Length 规定字符长度 DateRequired 确保字段有值 Email 邮箱格式 NumberRange 规定数字范围 IPAddress ip 地址格式 URL URL 格式 EqualTo 验证字段相等 Regexp 正则校验 自定义验证函数
- 函数名称:
validate_字段名
- 参数:
self, field
(表示要验证的字段) - 验证失败时,需要抛出指定异常
ValidationError
,验证通过返回True
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20# 导入需要的验证器类
from wtforms.validators import Length,ValidationError
# 创建一个表单类
class NameForm(FlaskForm):
# name = StringField('用户名:', validators=[Length(6, 20, '必须在6-20个字符之间')])
name = StringField('用户名:')
password = PasswordField('密码:')
submit = SubmitField('提交')
def validate_name(self, field):
if len(field.data) < 6:
raise ValidationError('用户名不能少于6个字符')
return True
def validate_password(self, field):
if not field.data:
raise ValidationError('密码不能为空')
return True
- 函数名称:
- 说明:浏览器默认会记录最后的请求状态,当是 POST 请求时,用户点击刷新按钮,浏览器会提示是否重新提交表单,但是这种情况绝大多数都是没有必要的;最好的解决方案就是将 POST 请求重定向到当前的地址(GET)
- 使用:
redirect
cookie
设置
resp.set_cookie(key, value, max_age, expires)
max_age
:高级浏览器使用,类型为整数单位秒expires
:IE-8 浏览器,类型为日期或时间戳,优先级低1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# 设置cookie
def set_cookie():
import time
from flask import make_response
from datetime import datetime, timedelta
resp = make_response('cookie已设置')
# 设置过期时间
# expires:兼容IE8及以下版本的浏览器,参数类型datetime或时间戳
# max_age:高级浏览器选用此参数,类型为整数,单位为s,优先级较高
# resp.set_cookie('name', 'dahua', max_age=10)
# expires = time.time() + 10
expires = datetime.utcnow() + timedelta(seconds=100)
resp.set_cookie('name', 'dahua', expires=expires)
return resp
获取
request.cookies.get('key')
1
2
3
4# 获取cookie
def get_cookie():
return request.cookies.get('name', '未设置')
删除
resp.delete_cookie(key)
1
2
3
4
5
6# 删除cookie
def del_cookie():
resp = make_response('cookie已删除')
resp.delete_cookie('name')
return resp
session
session[key] = value
有效期
app.config['SESSION_PERMANENT']
,设置为 False 浏览器关闭就失效,设置 True 后有效期才有意义app.config['PERMANENT_SESSION_LIFETIME']
,设置有效期,默认 31 天,也可以传递整数1
2
3
4
5
6
7
8
9
10
11
12# session是否永久生效,设置为False浏览器关闭后就失效
app.config['SESSION_PERMANENT'] = True
# session有效期,默认是31天,可以是一个整数,设置为永久生效才有意义
# print(app.config['PERMANENT_SESSION_LIFETIME'])
app.config['PERMANENT_SESSION_LIFETIME'] = 10
# 设置session
from flask import session
def set_session():
session['name'] = 'ergouzi'
return 'session已设置'
获取
session.get(key, 默认值)
1
2
3
4# 获取session
def get_session():
return session.get('name', '未设置')
删除
- 指定:
session.pop(key, None)
- 所有:
session.clear()
1
2
3
4
5
6
7
8# 删除session
def del_session():
# 删除指定session
session.pop('name', None)
# 清空session,清空所有session
session.clear()
return 'session已删除'
- 指定: