简体   繁体   English

WTForms:在取消时禁用客户端验证

[英]WTForms: Disable client-side validation on cancel

What I'm asking for is actually quite simple.我要求的其实很简单。 I want to create a form with some fields and a submit and a cancel button.我想创建一个包含一些字段和一个提交和一个取消按钮的表单。 I want to use the quick_form template function of Flask-Bootstrap to keep overhead in my template low.我想使用 Flask-Bootstrap 的quick_form模板函数来降低模板中的开销。 My form looks like this:我的表格是这样的:

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')

The template:模板:

{% 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 %}

As one would suspect I want to validate and accept the input values on submit and skip validation on cancel .正如人们所怀疑的那样,我想在提交时验证并接受输入值,并在取消时跳过验证。 So my view function looks as expected.所以我的视图函数看起来像预期的那样。

@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)

Now if cancel is pressed there should logically be no validation and the redirect should take place.现在,如果按下取消,则逻辑上应该没有验证并且应该进行重定向。 However I run into the issue that my view function doesn't even get called if I press either submit or cancel due to the client-side validation.但是,我遇到的问题是,如果由于客户端验证而按下提交取消,我的视图函数甚至不会被调用。

<input class="form-control" id="name" name="name" required="" type="text" value="">

Is there a way to disable client-side validation on WTForms?有没有办法在 WTForms 上禁用客户端验证?

Since you use Flask-Bootstrap's quick_form() macro, you can just set novalidate parameter to True to disable client-side validation (it will set a novalidate attribute to your HTML <form> element):由于您使用 Flask-Bootstrap 的quick_form()宏,您可以将novalidate参数设置为True以禁用客户端验证(它将为您的 HTML <form>元素设置novalidate属性):

{{ wtf.quick_form(form, novalidate=True) }}

If you are using Bootstrap-Flask, the method is similar:如果你使用的是 Bootstrap-Flask,方法类似:

{{ render_form(form, novalidate=True) }}

The Required validator as well as the DataRequired and InputRequired which replace Required since version 3 of WTForms set the replace flag of the field.从 WTForms 的第 3 版开始, Required验证器以及DataRequiredInputRequired替换了Required ,设置了该字段的替换标志。 This flag is used to add the required attribute to the HTML representation of the field.此标志用于将required属性添加到字段的 HTML 表示中。 My workaround is to manually create a validate function.我的解决方法是手动创建验证函数。

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')

This way there is no validation on the client-side and it is ensured that the view function is called on every submit or cancel .这种方式在客户端没有验证,并确保在每次提交取消时调用视图函数。

Note笔记

An even simpler solution is to subclass the InputRequired validator and overwrite the field_flags dictionary.一个更简单的解决方案是将InputRequired验证器子类化并覆盖 field_flags 字典。

from wtforms.validators import InputRequired

class MyInputRequired(InputRequired):
    field_flags = ()

class SequenceForm(FlaskForm):
    name = StringField('Name:', validators=[MyInputRequired(), Length(1, 128)])

You could forbid rendering of the required attr.您可以禁止呈现required属性。

class MyTextInput(wtforms.widgets.TextInput):
    def __call__(self, field, **kwargs):
        kwargs['required'] = False
        return super().__call__(field, **kwargs)

For Python2 add args like this: super(MyTextInput, self)对于 Python2,添加这样的参数: super(MyTextInput, self)

and then:进而:

name = StringField('Name:', validators=[Required(), Length(1, 128)], widget=MyTextInput())

要禁用客户端表单验证,请将“novalidate”属性添加到模板中的 HTML <form>元素:

<form method="POST" novalidate>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM