Flask-表单使用
url_for
- 可以根据视图函数名构造对应的路由地址
- 带参的路由也可以构造,多出来的参数会自动作为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']
flask-wtf
库
-
**说明:**提供了简洁的书写形式,提供了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重定向GET
- **说明:**浏览器默认会记录最后的请求状态,当是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已删除'
- 指定:
-