如何从 Flask WTForms 验证错误生成 HTML5 良好的验证错误消息

问题描述 投票:0回答:1

我尝试使用 Flask WTForms 并组合一些 HTML 代码在网站上生成提交表单。目前为止涉及到的代码如下:

服务器.py:

from flask import Flask, render_template, request, url_for, redirect, flash, send_from_directory, jsonify
from flask_wtf import FlaskForm
from wtforms import StringField, IntegerField, SelectField, DateField, PasswordField, SubmitField, EmailField
from wtforms.validators import DataRequired, ValidationError, Email, NumberRange
from datetime import datetime, timedelta

class TestForm(FlaskForm):
    name = StringField(label='Name', validators=[DataRequired("You must include a name")])
    start_search = DateField(
        label='Start date', validators=[DataRequired()], default=datetime.now() + timedelta(days=1))
    end_search = DateField(
        label='End date', validators=[DataRequired()], default=datetime.now() + timedelta(days=2))
    submit = SubmitField(label="Submit")

app = Flask(__name__)

@app.route('/test', methods=['GET', 'POST'])
def test():
    form = TestForm()
    if form.validate_on_submit():
        return redirect('/success')
    return render_template('test.html', title='Test', form=form)

测试.html:

<form class="form" method="POST" id="form" style="display: block;">
{{ form.csrf_token() }}
<div class="container">
    <div class="row">
    {{ form.name.label }}
    {{ form.name(class="form-control") }}
    </div>

    <div class="row">
    {{ form.start_search.label }}
    {{ form.start_search(class="form-control") }}
    </div>

    <div class="row">
    {{ form.end_search.label }}
    {{ form.end_search(class="form-control") }}
    </div>

    <div class="row">
        {{ form.submit(class="form-control") }}
    </div>
</div>
</form>

网站:

一切都很好。如果我尝试在名称字段为空时提交,因为它具有 DataRequired 验证器,我会得到以下结果:

这很棒,但我想对字段进行一些自定义验证,例如,返回我已添加到名称字段的 DataRequired 中的自定义“您必须包含名称”错误,而不是我的默认值似乎正在得到。我在网上看到,在 html 表单定义上添加

novalidate
标签允许人们能够在字段旁边编写自定义错误,如下所示:

<form class="form" method="POST" id="form" style="display: block;" novalidate>
{{ form.csrf_token() }}
<div class="container">
    <div class="row">
    {{ form.name.label }}
    {{ form.name(class="form-control") }}
    {% for error in form.name.errors %}
    <span style="color: red;">[{{ error }}]</span>
    {% endfor %}
    </div>

    <div class="row">
    {{ form.start_search.label }}
    {{ form.start_search(class="form-control") }}
    </div>

    <div class="row">
    {{ form.end_search.label }}
    {{ form.end_search(class="form-control") }}
    </div>

    <div class="row">
        {{ form.submit(class="form-control") }}
    </div>
</div>
</form>

这很棒,但这不是我想要的。 我想生成与之前看到的相同的漂亮弹出窗口,只需一条自定义错误消息。此外,当我添加

novalidate
标签时,重新加载网站会弹出“确认表单重新提交”弹出窗口,这以前没有发生过,我不明白为什么:

以下问题类似,但尚未完全回答: Flask表单验证错误提示信息 https://www.reddit.com/r/flask/comments/lkg4w6/understanding_the_flask_wtforms_validation_popup/

感谢您提前提供的帮助。

我正在使用

  • 烧瓶=2.3.2
  • 烧瓶-wtf=1.2.1
  • wtforms=3.0.1
  • python=3.8
javascript html forms validation flask-wtforms
1个回答
1
投票

表单验证的主题是一种元问题。你可以把它分成两部分:

  1. 提交前是否在浏览器中使用 javascript 验证表单。
  2. 如何使用wtforms在服务器端验证上添加自定义验证。 我认为对于是否在客户端验证和服务器端验证没有一个简单的答案。可以用 JavaScript 制作一个更加用户友好的验证 UI,但它并不能完全消除在服务器端进行验证的需要。我倾向于结合使用两者。

WTForms 无法帮助浏览器中的验证,为此您需要编写一些 JavaScript 来对浏览器中的表单事件做出反应。浏览器仅内置最少的验证,例如当您为 wtforms 中的字段指定 required 时,这会导致浏览器在输入上生成 required 属性,并且浏览器将向用户提供通用提示以在填写该字段之前它提交了它。这些通用提示就像您看到的“请填写此字段”弹出窗口一样。一旦浏览器实际提交字段,WTForms 的验证器实际上在服务器端运行,您可以在那里运行任意 python 代码以强制执行进一步的限制。 python 中的错误消息可以在用于呈现表单的 jinja 模板中显示为 form.errors 或 field.errors。 WTForms 文档中有一个(不完整的)示例

重新提交警告只是为了强制执行 POST 的语义,传统上,POST 用于引起服务器端状态的更改。如果您在提交后点击后退按钮,就会发生这种情况。当使用 POST 提交表单时,您想要做的是重新呈现包含错误消息的表单,这样用户就不会试图点击后退按钮重试。

© www.soinside.com 2019 - 2024. All rights reserved.