gpt4 book ai didi

forms - 使用 Flask 和 WTForms 在单个页面中显示多个表单

转载 作者:行者123 更新时间:2023-12-03 05:47:25 24 4
gpt4 key购买 nike

我在同一页面上有多个表单,将发布请求发送到同一处理程序在 flask 中。

我正在使用 wtforms 生成表单。

识别提交的表单的最佳方法是什么?

我目前正在使用action="?form=oneform"。我认为应该有一些更好的方法达到同样的目的?

最佳答案

上面的解决方案有一个验证错误,当一个表单导致验证错误时,两个表单都会显示一条错误消息。我改变了 if 的顺序来解决这个问题。

首先,使用不同的名称定义多个 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(): # notice the order
....
if form2.submit2.data and form2.validate(): # 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_subscribed():

def is_submitted():
"""Consider the form submitted if there is an active request and
the method is ``POST``, ``PUT``, ``PATCH``, or ``DELETE``.
"""
return _is_submitted() # bool(request) and request.method in SUBMIT_METHODS

当您调用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中)时,调用if form1.submit.data:中的.data在dict中添加一个键值<首先,然后if form2.submit.data:调用添加另一个键值,最后,字典会像这样:

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

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

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

更新

还有另一种方法可以在一个页面上处理多个表单。您可以使用多个 View 来处理表单。例如:

...
@app.route('/')
def index():
register_form = RegisterForm()
login_form = LoginForm()
return render_template('index.html', register_form=register_form, login_form=login_form)

@app.route('/register', methods=['POST'])
def register():
register_form = RegisterForm()
login_form = LoginForm()

if register_form.validate_on_submit():
... # handle the register form
# render the same template to pass the error message
# or pass `form.errors` with `flash()` or `session` then redirect to /
return render_template('index.html', register_form=register_form, login_form=login_form)


@app.route('/login', methods=['POST'])
def login():
register_form = RegisterForm()
login_form = LoginForm()

if login_form.validate_on_submit():
... # handle the login form
# render the same template to pass the error message
# or pass `form.errors` with `flash()` or `session` then redirect to /
return render_template('index.html', register_form=register_form, login_form=login_form)

在模板(index.html)中,您需要渲染两个表单并将action属性设置为目标 View :

<h1>Register</h1>
<form action="{{ url_for('register') }}" method="post">
{{ register_form.username }}
{{ register_form.password }}
{{ register_form.email }}
</form>

<h1>Login</h1>
<form action="{{ url_for('login') }}" method="post">
{{ login_form.username }}
{{ login_form.password }}
</form>

关于forms - 使用 Flask 和 WTForms 在单个页面中显示多个表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18290142/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com