WTForms:取消时禁用客户端验证
WTForms: Disable client-side validation on cancel
我的要求其实很简单。我想创建一个包含一些字段和一个 submit 和一个 cancel 按钮的表单。我想使用 Flask-Bootstrap 的 quick_form
模板函数来降低模板的开销。我的表单如下所示:
from flask_wtf import FlaskForm
from wtforms.validators import Required, Length
class SequenceForm(FlaskForm):
name = StringField('Name:', validators=[Required(), Length(1, 128)])
# some other fields here
submit = SubmitField('submit')
cancel = SubmitField('cancel')
模板:
{% extends 'base.html' %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block content %}
<div class="container">
<form method="POST">
<div class="row">
<div class="col-xs-12">
{{ wtf.quick_form(form, button_map={'submit': 'primary'}) }}
</div>
</div>
</form>
</div>
{% endblock %}
正如人们所怀疑的那样,我想在 submit 上验证并接受输入值,并在 cancel 上跳过验证。所以我的视图函数看起来符合预期。
@main.route('sequence/', methods=['GET', 'POST'])
def sequence():
form = SequenceForm()
if request.method == 'POST':
if 'submit' in request.form:
if form.validate_on_submit():
print(form.duration.data)
else:
return redirect(url_for('main.index'))
return render_template('sequence.html', form=form)
现在,如果按下 取消,逻辑上应该没有验证,应该进行重定向。但是我 运行 遇到了一个问题,即如果我按 submit 或 cancel 甚至不会调用我的视图函数,因为客户端验证。
<input class="form-control" id="name" name="name" required="" type="text" value="">
有没有办法在 WTForms 上禁用客户端验证?
自 WTForms 第 3 版起替换 Required
的 Required validator as well as the DataRequired and InputRequired 设置了字段的 replace 标志。此标志用于将 required 属性添加到字段的 HTML 表示中。我的解决方法是手动创建验证函数。
from wtforms.validators import ValidationError
def _required(form, field):
if not field.raw_data or not field.raw_data[0]:
raise ValidationError('Field is required')
class SequenceForm(FlaskForm):
name = StringField('Name:', validators=[_required, Length(1, 128)])
# some other fields here
submit = SubmitField('submit')
cancel = SubmitField('cancel')
这种方式在客户端没有验证,并且确保在每次 submit 或 cancel[=28= 时调用视图函数].
备注
一个更简单的解决方案是继承 InputRequired
验证器并覆盖 field_flags 字典。
from wtforms.validators import InputRequired
class MyInputRequired(InputRequired):
field_flags = ()
class SequenceForm(FlaskForm):
name = StringField('Name:', validators=[MyInputRequired(), Length(1, 128)])
您可以禁止呈现 required
属性。
class MyTextInput(wtforms.widgets.TextInput):
def __call__(self, field, **kwargs):
kwargs['required'] = False
return super().__call__(field, **kwargs)
对于 Python2 添加这样的参数:super(MyTextInput, self)
然后:
name = StringField('Name:', validators=[Required(), Length(1, 128)], widget=MyTextInput())
要禁用客户端表单验证,请将 'novalidate' 属性添加到模板中的 HTML <form>
元素:
<form method="POST" novalidate>
由于您使用 Flask-Bootstrap 的 quick_form()
宏,您只需将 novalidate
参数设置为 True
即可禁用客户端验证(它将设置novalidate
属性到 HTML <form>
元素):
{{ wtf.quick_form(form, novalidate=True) }}
如果你使用的是Bootstrap-Flask,方法类似:
{{ render_form(form, novalidate=True) }}
我的要求其实很简单。我想创建一个包含一些字段和一个 submit 和一个 cancel 按钮的表单。我想使用 Flask-Bootstrap 的 quick_form
模板函数来降低模板的开销。我的表单如下所示:
from flask_wtf import FlaskForm
from wtforms.validators import Required, Length
class SequenceForm(FlaskForm):
name = StringField('Name:', validators=[Required(), Length(1, 128)])
# some other fields here
submit = SubmitField('submit')
cancel = SubmitField('cancel')
模板:
{% extends 'base.html' %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block content %}
<div class="container">
<form method="POST">
<div class="row">
<div class="col-xs-12">
{{ wtf.quick_form(form, button_map={'submit': 'primary'}) }}
</div>
</div>
</form>
</div>
{% endblock %}
正如人们所怀疑的那样,我想在 submit 上验证并接受输入值,并在 cancel 上跳过验证。所以我的视图函数看起来符合预期。
@main.route('sequence/', methods=['GET', 'POST'])
def sequence():
form = SequenceForm()
if request.method == 'POST':
if 'submit' in request.form:
if form.validate_on_submit():
print(form.duration.data)
else:
return redirect(url_for('main.index'))
return render_template('sequence.html', form=form)
现在,如果按下 取消,逻辑上应该没有验证,应该进行重定向。但是我 运行 遇到了一个问题,即如果我按 submit 或 cancel 甚至不会调用我的视图函数,因为客户端验证。
<input class="form-control" id="name" name="name" required="" type="text" value="">
有没有办法在 WTForms 上禁用客户端验证?
自 WTForms 第 3 版起替换 Required
的 Required validator as well as the DataRequired and InputRequired 设置了字段的 replace 标志。此标志用于将 required 属性添加到字段的 HTML 表示中。我的解决方法是手动创建验证函数。
from wtforms.validators import ValidationError
def _required(form, field):
if not field.raw_data or not field.raw_data[0]:
raise ValidationError('Field is required')
class SequenceForm(FlaskForm):
name = StringField('Name:', validators=[_required, Length(1, 128)])
# some other fields here
submit = SubmitField('submit')
cancel = SubmitField('cancel')
这种方式在客户端没有验证,并且确保在每次 submit 或 cancel[=28= 时调用视图函数].
备注
一个更简单的解决方案是继承 InputRequired
验证器并覆盖 field_flags 字典。
from wtforms.validators import InputRequired
class MyInputRequired(InputRequired):
field_flags = ()
class SequenceForm(FlaskForm):
name = StringField('Name:', validators=[MyInputRequired(), Length(1, 128)])
您可以禁止呈现 required
属性。
class MyTextInput(wtforms.widgets.TextInput):
def __call__(self, field, **kwargs):
kwargs['required'] = False
return super().__call__(field, **kwargs)
对于 Python2 添加这样的参数:super(MyTextInput, self)
然后:
name = StringField('Name:', validators=[Required(), Length(1, 128)], widget=MyTextInput())
要禁用客户端表单验证,请将 'novalidate' 属性添加到模板中的 HTML <form>
元素:
<form method="POST" novalidate>
由于您使用 Flask-Bootstrap 的 quick_form()
宏,您只需将 novalidate
参数设置为 True
即可禁用客户端验证(它将设置novalidate
属性到 HTML <form>
元素):
{{ wtf.quick_form(form, novalidate=True) }}
如果你使用的是Bootstrap-Flask,方法类似:
{{ render_form(form, novalidate=True) }}