Flask 中 WTForm 字段的自定义验证

Custom validation for WTForm fileds in Flask

我使用了内置验证器,但其中 none 正在页面上打印一条消息。另外,我想创建一个自定义验证器来检查重复的用户名。功能我写好了,我是初学者,不知道怎么用。请解决问题。

from flask import Flask, app, render_template, request, url_for
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, PasswordField
from wtforms.validators import InputRequired, EqualTo, ValidationError

app = Flask(__name__)

app.config['SECRET_KEY'] = "PQrs12t46uvvrty567"

class MyForm(FlaskForm):
    username = StringField('Username', validators=[InputRequired(message="This field is required.")])
    password=PasswordField('Password', validators=[InputRequired(message=("enter the password"))])
    confirm_password=PasswordField('Confirm Password', validators=[EqualTo('password')])
    submit = SubmitField('Register') 


def isDuplicate():
    appdatabase={"Alis":"Smith","Mike":"Brown","Paul":"Miller"}
    form = MyForm()
    for user in appdatabase:
        if form.username == appdatabase[user]:
            raise ValidationError("Username already exists! Please choose another one.")


@app.route('/')
def base():
    form = MyForm()
    return render_template('customvalidator.html', form = form)

@app.route('/submitform', methods=["GET","POST"])
def submitform():
    form = MyForm()
    if form.validate_on_submit():
        return 'Form accepted successfully.'
    else:
        return 'Incorrect form data'

if __name__=="__main__":
    app.run(debug=True)

HTML 文件

<!DOCTYPE html>
<html>
    <head><title>My website</title></head>
    <body>
        <h1>Registration form</h1>  
        <form action="{{ url_for('submitform') }}" method="post">
            {{ form.csrf_token }}
            {{ form.username.label }} 
            {{ form.username }} 
            <ul> 
                {% for error in form.username.errors %}
                 <li style="color: red;">{{ error }} </li>              
                {% endfor %}
            </ul>
            <br>
            {{ form.password.label }}
            {{ form.password }} <br><br>
            {{ form.confirm_password.label }}
            {{ form.confirm_password }} <br><br>
            {{ form.submit}}
    </form>
      
    </body>
</html>

尝试将 isDuplicate 函数更改为:

def isDuplicate(form, field):
    appdatabase={"Alis":"Smith","Mike":"Brown","Paul":"Miller"}
    form = MyForm()
    for user in appdatabase:
        if form.username.data == appdatabase[user]:
            raise ValidationError("Username already exists! Please choose another one.")

请注意向函数添加的表单和字段参数,以允许将其用作自定义验证器。 form.username 也更改为 form.username.data 以访问用户名字段的数据。 (整个函数需要在表单之前定义。)
然后,您需要将此自定义验证器添加到表单中用户名字段的验证器列表中,如下所示:

username = StringField('Username', validators=[InputRequired(message="This field is required."),isDuplicate])

通过这些更改,自定义验证应该可以工作,但我们仍未解决自定义错误消息的问题。为此,请将 novalidate 属性添加到 HTML 表单标签。添加此项将禁用表单的默认验证并允许您显示自定义消息。

有了这个,我相信由于您处理表单提交的方式,消息仍然无法正常工作。当表单未通过验证时,您将希望显示相同的表单模板,而不是显示它们是否已提交。

我个人认为合并两个表单路由是最简单的选择。让路由定义表单,检查它何时得到验证,然后呈现表单模板。这将使您能够将所有内容放在一起,而不是在您只想显示带有一些添加的错误消息的相同模板时呈现不同的模板。

学分:

  • Custom validators(检查最后一点)
  • -这使我 了解如何禁用默认消息。