Flask Form表单
前提条件:
pip install flask-wtf
pip install wtforms
# 如安装失败,使用如下方式:
pip install flask-wtf -i https://pypi.tuna.tsinghua.edu.cn/simple/
pip install wtforms -i https://pypi.tuna.tsinghua.edu.cn/simple/
1 表单的编写
编写表单组件的代码,这里新建一个 forms.py
文件,项目结构以及表单组件的代码如下所示:
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
class RegisterForm(FlaskForm):
username = StringField(label="User Name:")
email = StringField(label="Email Address:")
password1 = PasswordField(label="Password:")
password2 = PasswordField(label="Confirm Password:")
submit = SubmitField(label="Create Account")
编写路由文件,这里主要是写要应用到表单组件的前端页面以及路由:
@app.route("/register")
def register_page():
form = RegisterForm()
return render_template("register.html", form=form)
前端页面如下所示:
{% extends "base.html" %}
{% block title%}
Register Page
{% endblock %}
{% block content%}
<body>
<div class="container">
<form method="POST" class="form-register" style="color:white">
<img class="mb-4" src="{{ url_for('static', filename='euansu.png') }}" style="width: 100px;height: 100px;margin-top: 30px;"/>
<h1 class="h3 mb-3 font-weight-normal">
Please Create your Account
</h1>
{{ form.username.label() }}
{{ form.username(class="form-control", placeholder="User Name") }}
{{ form.email.label() }}
{{ form.email(class="form-control", placeholder="Email Address") }}
{{ form.password1.label() }}
{{ form.password1(class="form-control", placeholder="Password") }}
{{ form.password2.label() }}
{{ form.password2(class="form-control", placeholder="Confirm Password") }}
<br />
{{form.submit(class="btn btn-lg btn-block btn-primary")}}
</form>
</div>
</body>
{% endblock %}
实现效果如下图所示:
这里的 img
是我本地的图片,也可以替换成你自己的,按照如下步骤操作即可:
-
在
Flask
项目的__init__py
文件中,配置静态文件的路径:app.static_folder = 'static'
-
在项目下创建
static
目录,目录结构如下所示。 -
访问路由,查看是否能够使用。
-
在前端
html
文件中,如果是jinjia2
代码块中,使用如下写法:<img class="mb-4" src="{{ url_for('static', filename='euansu.png') }}" style="width: 100px;height: 100px;margin-top: 30px;"/>
2 表单的提交
编写后端代码:
# 这里先只是进行一下模拟,并不实际创建账号
@app.route("/register", methods=["GET", "POST"])
def register_page():
form = RegisterForm()
if form.validate_on_submit():
# 创建用户
print("用户{username}创建成功".format(username=form.username.data))
return redirect(url_for('home_page'))
return render_template("register.html", form=form)
页面输入表单信息进行登录:
输入完成后跳转路由至用户家目录:
3 表单的验证
修改 forms.py
为如下内容:
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import Length, EqualTo, Email, DataRequired
class RegisterForm(FlaskForm):
username = StringField(label="User Name:", validators=[Length(min=2, max=32), DataRequired()])
email = StringField(label="Email Address:", validators=[Email(), DataRequired()])
password1 = PasswordField(label="Password:", validators=[Length(min=8, max=32), DataRequired()])
password2 = PasswordField(label="Confirm Password:",
validators=[Length(min=8, max=32), EqualTo('password1'), DataRequired()])
submit = SubmitField(label="Create Account")
页面验证:
这里可能有报错,如下所示:
验证邮箱需要单独安装 email_validator
,如下所示:
pip install email_validator
pip install email_validator -i https://pypi.tuna.tsinghua.edu.cn/simple/
再次校验,就能够正常输出不通过校验的信息。
4 flash消息
用户执行某些动作后,通常需要在页面显示一个提示消息。Flask
内置了相关的函数 flash()
, flash()
函数用来在视图函数里向模板传递提示消息,get_flashed_messages()
函数则用来在模板中获取提示消息。
使用方法:
from flask import flash
# 视图函数中直接调用即可
flash('Message')
flash()
函数在内部会把消息存储到 Flask 提供的 session
对象里。session
用来在请求间存储数据,它会把数据签名后存储到浏览器的 Cookie 中,所以我们需要设置签名所需的密钥:
app.config['SECRET_KEY'] = '08828e2a1c6e1e35cf020c09'
这个密钥值是个随机值,可以按照如下方式进行设置:
import os
os.urandom(12).hex()
如下是一个 flash()
函数的使用示例:
-
后端函数:
@app.route("/register", methods=["GET", "POST"]) def register_page(): form = RegisterForm() if form.validate_on_submit(): # 创建用户 print("用户{username}创建成功".format(username=form.username.data)) return redirect(url_for('home_page')) if form.errors != {}: for err_msg in form.errors.values(): print("{}".format(err_msg)) flash(f"There was an error with creating account:{err_msg}", category="danger") return render_template("register.html", form=form)
-
前端
html
:{% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} {% for category, message in messages %} <div class="alert alert-{{ category }}"> {{ message }} </div> {% endfor %} {% endif %} {% endwith %}
-
实现效果: