Python Flask WTF-从不执行提交时验证提交()

Python Flask WTF-从不执行提交时验证提交(),python,forms,validation,flask,wtforms,Python,Forms,Validation,Flask,Wtforms,我正在使用Flask WTF: 这是我的表格: from flask.ext.wtf import Form, TextField class BookNewForm(Form): name = TextField('Name') 这是控制器: @book.route('/book/new', methods=['GET', 'POST']) def customers_new(): form = BookNewForm() if form.is_submitted(

我正在使用Flask WTF:

这是我的表格:

from flask.ext.wtf import Form, TextField

class BookNewForm(Form):
    name = TextField('Name')
这是控制器:

@book.route('/book/new', methods=['GET', 'POST'])
def customers_new():
    form = BookNewForm()
    if form.is_submitted():
        print "submitted"
    if form.validate():
        print "valid"
    if form.validate_on_submit():
        flash("Successfully created a new book")
        return redirect(url_for('.books_show'))
    return render_template('views/books_new.html', form=form)
现在的问题是,如果你看我的print语句,它总是打印提交的,但它从不打印有效的,并且永远不会执行validate_on_submit()。为什么?

您可以打印错误

print form.errors


如果您遇到csrf错误,您应该在模板中设置form.csrf\u token

您没有在HTML表单中插入CSRF字段

<form method=post>
    {{ form.csrf_token }}
    {{ form.name }}
    <input type=submit>
</form>

如果在每次请求之前没有登录,我正在清除flask会话。这导致了这个问题

@main.before_request
def before_request():
    if not current_user.is_authenticated():
        # TODO clean sessions may cause CSRF missing issue
        session.clear()
        print "Session Cleared"
        return redirect(url_for('auth.login'))

在模板html文件中的标记后插入:

 {{ form.csrf_token }} 

当我试图在模板中的
FieldList
上迭代一个
FormField
时,我遇到了这个问题。我必须嵌入两个隐藏的标签元素,一个用于
字段列表
表单,另一个用于
字段表单
表单,搜索模板注释中的关键字“隐藏标签”

class ParamRangeForm(烧瓶形式):
minX=浮动字段()
maxX=浮动字段()
类别参数范围窗体(烧瓶窗体):
paramRanges=FieldList(FormField(ParamRangeForm))
submit=SubmitField('submit')
def loadParams(自):
对于[“p1”、“p2”、“p3”、“p4”]中的参数名:
prf=参数范围形式()
prf.minX=-100.9#浮点('-inf')
prf.maxX=100.5#浮点('-inf')
self.paramRanges.append_条目(prf)
...
{{rangesForm.hidden_tag()}}
参数
分钟
马克斯
{rangesForm.paramRanges%}
{{paramRange.hidden_tag()}}
p{{loop.index}
{{paramRange.minX}}
{{paramRange.maxX}
{%endfor%}
{{rangesForm.submit()}

我认为API已经改变了。也许可以尝试改变

from flask.ext.wtf import Form
致:


我花了几个小时调试Flask WTF的验证问题。与其他许多问题一样,这是一个CSRF验证问题。然而,我的问题并不是由我发现的任何共同问题引起的

CSRF的标准Flask WTF实现要求向浏览器交付两件东西

One:隐藏的CSRF表单字段,例如

<input id="csrf_token" name="csrf_token" type="hidden" value="ImYzODdmZTdhYTRlMmNkYWRjYmRlYWFmZjQxMDllZTQ1OWZmYzg3MTki.XKvOPg.gUCkF9j-vg0PrL2PRH-v43GeHu0">
如果其中任何一个丢失,浏览器将无法发送正确的CSRF验证。当然,这反过来会导致表单验证失败

如果表单中存在
csrf\u令牌
隐藏字段,但缺少会话cookie,则在提交表单时,您将收到以下响应

Bad Request
The CSRF session token is missing.
在我的例子中,由于代码中的错误,会话cookie丢失了。我需要在整个Flask站点上提供一个自定义HTTP头。我像这样把它包括进去

class LocalFlask(Flask):

    def process_response(self, response):
        response.headers['my-header'] = 'My Header Value'
        return response

app = LocalFlask(__name__)
但是,这会导致在
Flask.response.headers
方法上重新解析的任何内容失败。其中之一是Flaks WTF设置会话cookie HTTP头

这可以通过将
super()
方法添加到
LocalFlask
类中来解决,以便它继承
Flask
类中的方法

class LocalFlask(Flask):

    def process_response(self, response):
        response.headers['my-header'] = 'My Header Value'
        #LocalFlask inherits methods from Flask
        super(LocalFlask, self).process_response(response)
        return response

app = LocalFlask(__name__)

谢谢您的提示,但是“print form.errors”会打印{}。仍然是form.validate()返回false我想知道如何调试Flask表单验证问题。非常好,非常感谢!这就是问题所在!我的表格中没有包含csrf字段。尝试用
{{form.csrf}}
来解决它不起作用,但是执行:
{{form.hidden_tag()}
解决了问题!关于打印错误,您也是对的,很高兴知道它现在是如何正常工作的!很乐意帮忙。如果您运行的是WTForms 0.6或更高版本,
form.csrf
变成了
form.csrf\u token
,所以请注意这一点,但是
form.hidden\u tag()
同样有效。这让我感到噩梦。非常感谢。想知道为什么文档中缺少这一关键部分。谢谢WTF验证的链接。比较两个日期,如果开始日期大于结束日期,则给出错误。
from flask_wtf import Form
<input id="csrf_token" name="csrf_token" type="hidden" value="ImYzODdmZTdhYTRlMmNkYWRjYmRlYWFmZjQxMDllZTQ1OWZmYzg3MTki.XKvOPg.gUCkF9j-vg0PrL2PRH-v43GeHu0">
Set-Cookie: session=eyJjc3JmX3Rva2VuIjoiZjM4N2ZlN2FhNGUyY2RhZGNiZGVhYWZmNDEwOWVlNDU5ZmZjODcxOSJ9.XKvOPg.a3-W62MHvaGVkv2GYCi-dgpLE3Y; HttpOnly; Path=/
Bad Request
The CSRF session token is missing.
class LocalFlask(Flask):

    def process_response(self, response):
        response.headers['my-header'] = 'My Header Value'
        return response

app = LocalFlask(__name__)
class LocalFlask(Flask):

    def process_response(self, response):
        response.headers['my-header'] = 'My Header Value'
        #LocalFlask inherits methods from Flask
        super(LocalFlask, self).process_response(response)
        return response

app = LocalFlask(__name__)