【问题标题】:use flask-wtf form validations without an actual form在没有实际表单的情况下使用 flask-wtf 表单验证
【发布时间】:2020-12-26 18:30:05
【问题描述】:

我正在尝试在某些变量上使用 flask-wtf 表单验证器。表单验证的所有示例都使用实际表单进行验证。我想在没有表单的几个变量上使用验证器。下面是sn-ps。我试过这种方法,但没有用。我在 form.validate() 上得到 False 并且我得到 [] 错误列表。请指导我正确的流程。

#this is my form_validations.py
#########################################################################################################
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField
from wtforms.validators import DataRequired, Email, Length


class SignUpForm(FlaskForm):
    username = StringField('username', validators=[DataRequired(), Length(min=1, max=50)])
    email = StringField('email', validators=[DataRequired(), Email()])
    mobile = StringField('mobile', validators=[DataRequired(), Length(min=10, max=15)])

#########################################################################################################

#this is the function where I want to use the form validations.
def userSignUp():
    username = request.form['username']
    email = request.form['email']
    mobile = request.form['mobile']
    form = {
        "username" : str(username),
        "email": str(email),
        "mobile": str(mobile)
    }
    formData = MultiDict(mapping=form)
    print(formData)
    form = SignUpForm(formData)
    if form.validate():
        output = {"result": "success"}
    else:
        output = {"result": "failed"}
    # print(form.validate(),form.username.errors,form.email.errors,form.mobile.errors)
    return jsonify(output)

【问题讨论】:

  • 你设置CSRF with Flask-WTForms了吗?如果 CSRF 令牌有问题,则字段错误将为空。
  • @KarlSutt 是的,我认为这是 csrf_token 问题。我现在可以看到 form.errors 中缺少 csrf_token。你知道如何解决这个问题吗?我在本地主机上运行烧瓶并使用静态 html 文件 file:///C:/Users/hellohackers/Documents/GitHub/myapps/routes_use/signup.html 中的 api。我已经设置了烧瓶仍然存在 csrf 问题的 CSRF。
  • 如果您已经按照docs 中的描述设置了 CSRF,也许您在提交表单时没有发送令牌?您的 HTML 表单应包含对 {{ form.csrf_token }} 的调用。
  • @KarlSutt iam 没有使用 form.csrf_token 因为最后我只会将flask api用于移动应用程序。我是否必须先向客户端发送 csrf_token,然后对于其他请求,客户端需要向我发送 csrf_token 以进行 api 调用?
  • 啊哈,明白了。在这种情况下,我会放弃 Flask-WTF 并直接使用 WTForms。您可以在表单类定义中只使用from wtforms import Form 而不是from flask_wtf import FlaskForm 并将FlaskForm 替换为Form。其他一切都应该按原样工作。请务必查看this post,了解 REST API 安全性。

标签: python flask flask-wtforms wtforms


【解决方案1】:

这是一个简化的例子。

路线:

@app.route("/signup", methods=["GET", "POST"])
def signup():
    form = SignUpForm()
    if form.validate_on_submit():
        app.logger.info(f'Form validated - data: {form.data}')
        # redirect somewhere upon success...
        # return redirect('/somewhere')

    return render_template("signup.html", form=form)

类代码:

class SignUpForm(FlaskForm):
    username = StringField('username', validators=[validators.DataRequired(), validators.Length(min=1, max=50)])
    email = StringField('email', validators=[validators.DataRequired(), validators.Email()])
    mobile = StringField('mobile', validators=[validators.DataRequired(), validators.Length(min=10, max=15)])

对我端(验证器)稍作修改,因为我是这样导入的:

from wtforms import (
    Form, validators, widgets, FieldList,
    BooleanField, TextField, IntegerField, SelectField, SelectMultipleField,
    TextAreaField, StringField, SubmitField
 )

模板:

{% extends "base.html" %}
{% block title %}Sign up{% endblock %}

{% block subtitle %}Sign up{% endblock %}

{% block content %}

<h1>Sign up page</h1>

{% if form.is_submitted() and form.errors|count > 0 %}
<div class="alert alert-danger alert-dismissible fade show" role="alert">
    {{ form.errors|count }} error(s):
    <ul>
    {% for field_name, field_errors in form.errors|dictsort if field_errors %}
        {% for error in field_errors %}
            <li>{{ form[field_name].label }}: {{ error }}</li>
        {% endfor %}
    {% endfor %}
    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{% endif %}

<div class="row">
    <div class="col">
        <form class="row g-3" method="post" action="{{ url_for('signup') }}" class="form-inline">
        {{ form.csrf_token }}
        <div class="mb-3 col-md-4">
            <label for="username" class="form-label">Username</label>
            {{ form.username(class="form-control") }}
        </div>
        <div class="mb-3 col-md-4">
            <label for="email" class="form-label">Email</label>
            {{ form.email(class="form-control") }}
        </div>
        <div class="mb-3 col-md-4">
            <label for="mobile" class="form-label">Mobile</label>
            {{ form.mobile(class="form-control") }}
        </div>
        <div class="mb-3">
            <button type="submit" id="save" name="save" class="btn btn-success" value="save">Save</button>
        </div>
        </form>
    </div>
</div>

{% endblock %}

我正在使用 Bootstrap,所以你可以看到我让 Flask_wtf 自动生成表单字段但应用某些类。但是,我手动添加了一个提交按钮,但您将其作为可选字段包含在表单中。您也可以自己添加所有表单字段,然后确保它们保留其原始名称。注意:我也添加了隐藏的 CRSF 字段(自动填充)。

关键是使用 validate_on_submit 来强制验证表单并填充错误列表。如您所见,模板可以迭代错误列表并将它们显示为列表项。


表单如下所示:

【讨论】:

    猜你喜欢
    • 2015-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-13
    • 2016-09-20
    相关资源
    最近更新 更多