我尝试使用 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/
感谢您提前提供的帮助。
我正在使用
表单验证的主题是一种元问题。你可以把它分成两部分:
WTForms 无法帮助浏览器中的验证,为此您需要编写一些 JavaScript 来对浏览器中的表单事件做出反应。浏览器仅内置最少的验证,例如当您为 wtforms 中的字段指定 required 时,这会导致浏览器在输入上生成 required 属性,并且浏览器将向用户提供通用提示以在填写该字段之前它提交了它。这些通用提示就像您看到的“请填写此字段”弹出窗口一样。一旦浏览器实际提交字段,WTForms 的验证器实际上在服务器端运行,您可以在那里运行任意 python 代码以强制执行进一步的限制。 python 中的错误消息可以在用于呈现表单的 jinja 模板中显示为 form.errors 或 field.errors。 WTForms 文档中有一个(不完整的)示例。
重新提交警告只是为了强制执行 POST 的语义,传统上,POST 用于引起服务器端状态的更改。如果您在提交后点击后退按钮,就会发生这种情况。当使用 POST 提交表单时,您想要做的是重新呈现包含错误消息的表单,这样用户就不会试图点击后退按钮重试。