python - flask-bootstrap 在一页中有两种形式

标签 python flask flask-wtforms flask-bootstrap

我打算在我的 Flask 应用程序的一个页面中放置两个表单,一个用于编辑一般用户信息,另一个用于重置密码。模板看起来像这样

{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

{% block page_content %}                                                   
<div class="page-header">                                                  
    <h1>Edit Profile</h1>
</div>

{{ wtf.quick_form(form_profile, form_type='horizontal') }}                 

<hr>

{{ wtf.quick_form(form_reset, form_type='horizontal') }}                   

<hr>
{% endblock %} 

每个表单都有一个提交按钮。

在路由函数中,我试过这样将两种形式分开

form_profile = ProfileForm()
form_reset = ResetForm()

if form_profile.validate_on_submit() and form_profile.submit.data:
    ....
if form_reset.validate_on_submit() and form_reset.submit.data:
    .....

但是没有用。当我单击 ResetForm 中的按钮时,将执行 ProfileForm 验证逻辑。

我怀疑问题是 wtf.quick_form() 创建了两个相同的提交按钮,但不确定。

遇到这种情况怎么办? bootstrap/wtf.html 模板可以处理这种情况吗?

最佳答案

用不同的名称定义这两个 SubmitField,如下所示:

class Form1(Form):
    name = StringField('name')
    submit1 = SubmitField('submit')

class Form2(Form):
    name = StringField('name')
    submit2 = SubmitField('submit')

然后在view.py中:

....
form1 = Form1()
form2 = Form2()

if form1.submit1.data and form1.validate_on_submit():  # notice the order 
....
if form2.submit2.data and form2.validate_on_submit():  # notice the order 
....

至此问题解决

如果您想深入了解,请继续阅读。

这是validate_on_submit():

    def validate_on_submit(self):
        """
        Checks if form has been submitted and if so runs validate. This is
        a shortcut, equivalent to ``form.is_submitted() and form.validate()``
        """
        return self.is_submitted() and self.validate()

这里是 is_submitted():

    def is_submitted(self):
        """
        Checks if form has been submitted. The default case is if the HTTP
        method is **PUT** or **POST**.
        """

        return request and request.method in ("PUT", "POST")

当您调用 form.validate_on_submit() 时,无论单击哪个提交按钮,它都会检查表单是否已通过 HTTP 方法提交。所以上面的小技巧就是添加一个过滤器(检查提交是否有数据,即form1.submit1.data)。

此外,我们改变了 if 的顺序,所以当我们点击一​​个提交时,它只调用这个表单的 validate(),防止两个表单的验证错误。

故事还没有结束。这是.data:

@property
def data(self):
    return dict((name, f.data) for name, f in iteritems(self._fields))

它返回一个包含字段名称(键)和字段数据(值)的字典,但是,我们的两个表单提交按钮具有相同的名称提交(键)!

当我们点击第一个提交按钮(在 form1 中)时,来自 form1.submit1.data 的调用返回一个这样的字典:

temp = {'submit': True}

毫无疑问,当我们调用 if form1.submit.data: 时,它返回 True

当我们点击第二个提交按钮(在 form2 中)时,调用 .data in if form1.submit.data: add a key-value in dict < strong>首先,然后来自if form2.submit.data: 的调用添加另一个键值,最后,dict 将如下所示:

temp = {'submit': False, 'submit': True}

现在我们调用 if form1.submit.data:,它返回 True,即使我们点击的提交按钮是在 form2 中。

这就是为什么我们需要用不同的名称定义这两个SubmitField。顺便说一下,感谢阅读(到这里)!

感谢 nos 的通知,他添加了关于 validate() 的问题,请查看下面的评论!

关于python - flask-bootstrap 在一页中有两种形式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39738069/

相关文章:

python - Pandas to_sql 不创建文件

python - 在生产环境中在 Windows 上部署 Flask

python - 如何跟踪 Flask-WTF 中的表单字段变化?

python - 使用 flask-wtforms 更改 textarea 的值

python - 如何使用 lightgbm.cv 进行回归?

python - Pandas 汇总统计的经济状况调查有何不同?

python - opencv4nodejs如何计算拉普拉斯方差的模糊度

python - 安装 Flask 1.0.2(Jinja2 和 Werkzeug)时的需求问题

python - 部署许多不相关的 rest ml 模型

python - 使用来自 SQLAlchemy 对象的数据在 flask 中预填充 WTforms