【Flask】Flask Form表单

时间:2024-03-26 07:25:21

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 是我本地的图片,也可以替换成你自己的,按照如下步骤操作即可:

  1. Flask 项目的 __init__py 文件中,配置静态文件的路径:

    app.static_folder = 'static'
  2. 在项目下创建 static 目录,目录结构如下所示。

  3. 访问路由,查看是否能够使用。

  4. 在前端 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() 函数的使用示例:

  1. 后端函数:

    @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)

  2. 前端 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 %}

  3. 实现效果: