具有无缝用户体验的 WTForms 错误处理

WTForms error handling with seamless user experience

我是 WTForms 的新手,根据我目前所学,我发现验证错误处理有点棘手。

首先,我无法实现原生 HTML <input required >;

其次,当表单验证失败时,我必须重新呈现表单所在的页面模板,如果我的表单放在页面底部,用户将看到页面 'refreshed' 并且不知道发生了什么。

有没有人对如何更无缝地集成 WTForms 有建议?欢迎任何意见、资源、网址、代码示例,谢谢!

以下是我的一些相关代码:

# /forms.py
from wtforms import Form, BooleanField, StringField, PasswordField, validators

class RegistrationForm(Form):
    email = StringField('Email Address', [
        validators.required(),
        validators.Email(message='Please enter a valid email address'),
        validators.length(min=6, max=35)
    ])
    password = PasswordField('New Password', [
        validators.required(),
        validators.DataRequired(),
        validators.length(min=6, max=35)
    ])

# /views.py
from flask import Flask, Blueprint, flash, render_template, redirect, request, url_for
from forms import RegistrationForm, LoginForm

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def index():
    form = RegistrationForm()
    context = {
        "form": form
    }
    if request.method == 'POST' and form.validate():
        submitted_form = request.form
        return redirect('/welcome')
    else:
        return render_template('form.html', context = context)

# /form.html
<form class="form" action="" method="POST" name="register">
  {% for field_name, field_errors in context.reg_form.errors|dictsort if field_errors %}
    {% for err in field_errors %}
      <li class="error">{{ context.reg_form[field_name].label }}: {{ err }}</li>
    {% endfor %}
   {% endfor %}

   <ul class="form-fields center">
     <li class="form-field">
     {{ context.form.email(class='email', placeholder='email') }}
     </li>
     <li class="form-field">
     {{ context.form.password(class='password', placeholder='password') }}
     </li>
   </ul>
</form>

为了更好地体验 Flask 中的表单,您应该使用 Flask-WTF extension。安装它:

$ pip install flask-wtf

导入它

from flask.ext.wtf import Form

并将其与 wtforms 模块一起使用。

.py 文件:

from flask.ext.wtf import Form
from wtforms import StringField, SubmitField
from wtforms.validators import Required

class NameForm(Form):
    name = StringField('What is your name?', validators=[Required()])
    submit = SubmitField('Submit')

.html 文件:

<form method="POST">
{{ form.name.label }} {{ form.name() }}
{{ form.submit() }} #this is your submit button
</form>

据我了解,WTForm 总是需要刷新页面才能显示错误。我解决这个问题的方法是让前端为我验证表单。不知道你的情况是否可行,但我已经使用 AngularJS 来解决这个问题。这很容易,如果您需要简单的验证,如电子邮件格式、密码长度等,则不需要一行代码,这一切都由 html 属性完成。您甚至可以禁用提交按钮,直到您的表单准备就绪。 看看这个 CodePen

如果仍然需要,您可以使用此滚动到页面底部:

var objDiv =     document.getElementById("your_div");
objDiv.scrollTop = objDiv.scrollHeight

如果您需要一个更强大的解决方案,您可能会想出一个 API 对您要验证的任何字段 return 真或假。然后让 angular 发出一个 http 请求以在您键入时检查它,这样您可以 100% 确定您的表单将被验证。但是根据您检查的内容,您可能会暴露安全漏洞。在 Ng-Newsletter

上有一篇关于此的优秀博客 post