无法解决烧瓶中的验证错误

时间:2018-03-26 14:02:36

标签: python flask wtforms flask-wtforms

我是烧瓶开发的新手。我在Flask中遇到了一个特殊的验证错误。我的主要代码如下:

from flask import Flask,render_template,redirect,url_for,session,request
from flask_wtf import FlaskForm
from wtforms.validators import InputRequired
from wtforms import TextAreaField,SelectField,StringField

app = Flask(__name__)
app.config['SECRET_KEY'] = 'MySecret!'

def get_choices():
    names = [
               (1,"George"),
               (2,"Musk"),
               (3,"Stevens")
            ]
    return names

@app.route('/',methods=["GET","POST"])
def index():
    class TestForm(FlaskForm):
        name = StringField("Name",validators=[InputRequired()])
        lastname = SelectField("Lastname",choices=get_choices())

    t = TestForm()
    if request.method == "POST":
        if t.validate_on_submit():
            name = t.name.data
            lastname = t.lastname.data
            return "<h1> {} and {} </h1>".format(name,lastname)
        else:
            return "Validation Failed !!"

    return render_template('index.html',form=t)

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

我的index.html的代码如下:

<html>
<head>
    <title>Index form</title>
</head>
<body>
    <form action="" method="POST">
        {{ form.csrf_token }}
        {{ form.name.label }}
        {{ form.name }}
        {{ form.lastname.label }}
        {{ form.lastname }}
        <input type="submit" value="Submit">
    </form>
</body>
</html>

每次我提交表格时,我都会收到表格未经验证的消息。我不知道我哪里出错了。我必须故意将类定义保留在路由函数中,以便我可以模拟运行时情况,其中我不确定从运行时到内容。

请指导我问题的位置,也有人可以给我一些提示是否有办法调试Flask中的上述验证错误?

提前致谢。

1 个答案:

答案 0 :(得分:0)

根据@davidism建议,我使用t.errors进行了调试。 我发现问题是由于将选项映射到SelectField中的整数。

有两种方法可以摆脱这个错误:

  1. 在表单的coerce=int中添加lastname以获得动态选择 值(例如:1,2,3等)。
  2. 传递字符串作为第一个参数 names列表。
  3. 解决方案1:

    from flask import Flask,render_template,redirect,url_for,session,request
    from flask_wtf import FlaskForm
    from wtforms.validators import InputRequired
    from wtforms import TextAreaField,SelectField,StringField
    
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'MySecret!'
    
    def get_choices():
        names = [
                   (1,"George"),
                   (2,"Musk"),
                   (3,"Stevens")
                ]
        return names
    
    @app.route('/',methods=["GET","POST"])
    def index():
        class TestForm(FlaskForm):
            name = StringField("Name",validators=[InputRequired()])
            lastname = SelectField("Lastname",choices=get_choices(), coerce=int)
    
        t = TestForm()
        if request.method == "POST":
            if t.validate_on_submit():
                name = t.name.data
                lastname = t.lastname.data
                return "<h1> {} and {} </h1>".format(name,lastname)
            else:
                print t.errors
                return "Validation Failed !!"
    
        return render_template('index.html',form=t)
    
    if __name__ == "__main__":
        app.run(debug=True)
    

    提交表格后我得到了:

    output

    获取1作为姓氏可能不是您期望的值。 您可以使用字符串值作为选择的第一个参数;在这种情况下names列表。

    解决方案2:

    因此,如果我们删除coerce属性并更新我们的选择列表,如:

    from flask import Flask,render_template,redirect,url_for,session,request
    from flask_wtf import FlaskForm
    from wtforms.validators import InputRequired
    from wtforms import TextAreaField,SelectField,StringField
    
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'MySecret!'
    
    def get_choices():
        names = [
                   ("George","George"),
                   ("Musk","Musk"),
                   ("Stevens","Stevens")
                ]
        return names
    
    @app.route('/',methods=["GET","POST"])
    def index():
        class TestForm(FlaskForm):
            name = StringField("Name",validators=[InputRequired()])
            lastname = SelectField("Lastname",choices=get_choices())
    
        t = TestForm()
        if request.method == "POST":
            if t.validate_on_submit():
                name = t.name.data
                lastname = t.lastname.data
                return "<h1> {} and {} </h1>".format(name,lastname)
            else:
                print t.errors
                return "Validation Failed !!"
    
        return render_template('index.html',form=t)
    
    if __name__ == "__main__":
        app.run(debug=True)
    

    这一次,我们得到:

    output of solution 2

    现在它作为姓氏是有道理的。

    <强>参考文献: