【问题标题】:Dynamic WTForm field is not validated动态 WTForm 字段未验证
【发布时间】:2017-08-23 21:10:39
【问题描述】:

如果您dynamically add a field to a WTForms form,则不会验证新添加的字段(即使您添加了验证器)。

例如,在 Flask 中:

@app.route('/add', methods=['GET', 'POST'])
def add():
    if 'state' not in session:
        session['state'] = 1

    form = MyForm()

    if request.method == 'POST' and form.validate():
        if session['state'] == 1:
            setattr(
                MyForm,
                'asd',
                StringField(
                    'asdfield',
                    validators = [
                        DataRequired(),
                        Length(min=1)
                    ]
                )
            )
            form = MyForm()
            session['state'] = 2
            return render_template(
                'add.html',
                form=form
            )
        print(len(form.asd.data)) # can equal 0
        session['state'] = 1
        return redirect('/add')
    return render_template(
        'add.html',
        form=form
    )

我相信这是因为每次访问 /add 时都会运行 form = MyForm(),因此即使 session['state'] == 2 在没有动态添加字段的默认表单上运行 form.validate() .因此,该字段不能成为表单验证过程的一部分。

如何正确解决这种行为?如果不可能,那么如何动态地将字段添加到现有表单中,以使所有字段在提交时都得到正确验证?

【问题讨论】:

    标签: python flask wtforms flask-wtforms


    【解决方案1】:

    由于您在添加字段之前调用validate(),自然无法验证尚不存在的字段。也就是说,您不想将字段添加到 instance 而不是 class。这是因为由于 WTForms 在构造时处理其输入数据,因此向实例添加字段几乎是一件毫无意义的事情。

    如果你的字段名是静态的,你可以使用del技巧详解here

    如果它是动态的,您可以改为遵循文档中的 dynamic form composition pattern

    由于我已经详细讨论了这一点,我将在此处链接我之前的示例: Wtfforms dynamic generation

    【讨论】:

    • 我实际上已经提前做到了,并且确实有效,但是我忘记添加一部分代码以在 session['state']==2 时显示错误(因此让我相信没有验证)。我还应该提到,必须使用 delattr 删除动态字段,否则它们将永远存在。
    猜你喜欢
    • 2019-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多