Python 烧瓶-表格:验证始终为假

Python 烧瓶-表格:验证始终为假,python,validation,flask,wtforms,Python,Validation,Flask,Wtforms,首先,我是python和Flask的新手,如果我的问题很愚蠢,我很抱歉。我搜索了一下,但没有找到答案(我想这应该是一个“简单”的答案) 我想在我的网站上添加一个联系人页面,我发现了,所以我照做了。 在表单验证之前,一切正常。我只使用必需的和表单。validate()始终返回false。如果我不接触我的代码,并且删除了form类中的所有必需项,那么它就可以正常工作,form.validate()返回true 我真的不明白为什么,我读了很多应该使用validate\u on\u submit(),但

首先,我是python和Flask的新手,如果我的问题很愚蠢,我很抱歉。我搜索了一下,但没有找到答案(我想这应该是一个“简单”的答案)

我想在我的网站上添加一个联系人页面,我发现了,所以我照做了。 在表单验证之前,一切正常。我只使用必需的表单。validate()始终返回false。如果我不接触我的代码,并且删除了form类中的所有必需项,那么它就可以正常工作,form.validate()返回true

我真的不明白为什么,我读了很多应该使用validate\u on\u submit(),但如果我使用它,我会得到一个错误:“'ClassName'对象没有属性'validate\u on\u submit'*

以下是代码的相关部分:

Index.py

@app.route('/contact', methods=['GET','POST'])
def contact():
form = ContactForm()

if request.method == 'POST':
    if form.validate() == False:
        flash('All Fields are required.')
        return render_template('contact.html', form=form)
    else:
        return 'Form posted'
elif request.method == 'GET':
    return render_template('contact.html', form=form)
from wtforms import Form, TextField, TextAreaField, SubmitField, validators,ValidationError 

class ContactForm(Form):
  name = TextField("Name", [validators.Required()])
  email = TextField("Email")
  subject = TextField("Subject")
  message = TextAreaField("Message")
  submit = SubmitField("Send")
forms.py

@app.route('/contact', methods=['GET','POST'])
def contact():
form = ContactForm()

if request.method == 'POST':
    if form.validate() == False:
        flash('All Fields are required.')
        return render_template('contact.html', form=form)
    else:
        return 'Form posted'
elif request.method == 'GET':
    return render_template('contact.html', form=form)
from wtforms import Form, TextField, TextAreaField, SubmitField, validators,ValidationError 

class ContactForm(Form):
  name = TextField("Name", [validators.Required()])
  email = TextField("Email")
  subject = TextField("Subject")
  message = TextAreaField("Message")
  submit = SubmitField("Send")
contact.html

<div id="contact">
    {% for message in get_flashed_messages() %}
        <div class="flash">{{ message }}</div>
    {% endfor %}
  <form action="{{ url_for('contact') }}" method=post>

    {{ form.name.label }}
    {{ form.name }}

    {{ form.email.label }}
    {{ form.email }}

    {{ form.subject.label }}
    {{ form.subject }}

    {{ form.message.label }}
    {{ form.message }}

    {{ form.submit }}
  </form>
 </div>

{get_Flash_messages()%中的消息为%s}
{{message}}
{%endfor%}
{{form.name.label}
{{form.name}
{{form.email.label}
{{form.email}
{{form.subject.label}
{{form.subject}}
{{form.message.label}
{{form.message}}
{{form.submit}
即使我在Name字段中写了一些东西,我也从未得到“Form posted”字符串


提前感谢,

您必须使用请求中的值初始化表单实例:

from flask import request

@app.route('/contact', methods=['GET','POST'])
def contact():
    form = ContactForm(request.form)
    if request.method == "POST" and form.validate():
        # do something with form
        # and probably return a redirect
    return render_template("contact.html", form=form)
这里有一个比您在问题中链接的教程更好的教程:


请查看教程中的模板呈现代码,确保呈现表单字段错误。如果表单已发布但未验证,则代码将通过
呈现\u模板
,表单实例包含字段验证错误(请再次参阅教程和WTForms文档以了解详细信息)。

我总是无法通过表单。请在提交时验证()当我按照Miguel Grinberg的书“Flask Web Development”中的演示代码测试登录表单时。所以我想我应该找到一种调试的方法

我采用的调试方法是将以下代码添加到app/auth/views.py:

flash(form.errors)
然后,当我运行到登录页面时,它会显示罪魁祸首:

errors={'csrf_token': ['CSRF token missing']}

因此,我建议使用form.errors消息进行调试。

刚刚遇到了这个问题,解决方案是在模板中的表单下方添加
隐藏标签

...
<form action="{{ url_for('contact') }}" method=post>
{{ form.hidden_tag() }}
...
。。。
{{form.hidden_tag()}}
...

作为@Paul Vergeev,只需添加:

<form action="{{ url_for('contact') }}" method=post>
{{ form.csrf_token }}
将在html代码中包含所有隐藏的输入字段;但它们不会显示在页面上

{{ form.csrf_token }}
将只在html代码中包含隐藏的csrf_令牌输入字段;但它们不会显示在页面上

{{ form.csrf_token }}
还有一件事要做:您必须配置应用程序的
密钥
。为此,请在应用程序初始化的下方,即在app=Flask(\uu name\uuu)之后添加
app.config[“SECRET\u KEY”]=“一个您不会忘记的密钥”


所有这些都是WTForms验证器保护您的站点不受CSRF(通常发音为c-surf)影响的一种方法。您还可以阅读有关CSRF的更多信息。

@SARose此操作有效,因为否则会发生以下情况:–由于缺少CSRF令牌,验证失败。所以为了修复它,我们需要在表单中插入CSRF令牌作为隐藏的输入值。所以
{{form.hidden_tag()}
实际上在HTML中插入了类似的内容:
。csrf令牌现在与表单一起发送,验证通过。这不再解决问题。请参阅下面与CSRF令牌相关的修复。这是我的案例中的错误。我使用form.hidden_字段而不是form.hidden_tag()。你救了我的命我刚开始用Flask开发,我不知道如何调试。谢谢,下面是一个用法示例:根据您的注释,我可能会得到错误:
CSRF令牌不匹配
。我已经在网上搜索过了,但是他们没有为我工作,你知道这个问题吗?我已经通过
{{form.hidden_tag()}
{form.csrf_token}}
在表单中设置了csrf,谢谢@John Mutuma。。。这节省了我的时间:)