使用Flask和Flask-WTF,我想重定向到一个带有复选框的表单的页面。 我有一个初始搜索页面,其中有一个名为“SearchForm”的表单,在用户搜索之后,我将其重定向到一个结果页面,其中包含相同的SearchForm,然后是结果的列表视图。这使用户可以在结果页面上再次搜索。
这是我的表格:
class SearchForm(Form):
"""Search form class"""
from app.utils.translation import Translation
criteria = StringField(Translation.label('search'), validators=[DataRequired()])
all_employees = BooleanField(Translation.label('all_employees'), validators=[])
现在,当用户提交表单时,我可以像这样实例化它:
form = SearchForm(request.form)
我可以使用(例如):
来获取数据form.data['all_employees']
如果我不选中该复选框,WTForms会正确地将all_employees解析为 False 。 我重定向到其上具有相同表单的结果页面,并且我想使用用户刚刚提交的数据呈现该表单。所以我这样做:
return redirect(url_for('employees.search',
criteria=form.data["criteria"],
all_employees=form.data["all_employees"]
))
在搜索表单上,我使用查询字符串(URL)变量再次实例化表单:
form = SearchForm(request.args)
现在问题是因为form.data ['all_employees'] 的值为“False”,所以选中复选框。这是HTML的正常行为,只有在选中该复选框时才会传递复选框值。因此,如果存在值(并且“False” 一个值),则会选中该复选框。
我可以在我的重定向中使用类似的东西解决这个问题:
all_employees='y' if form.data['all_employees'] else ''
但这意味着我必须不断为每个重定向中的每个复选框字段执行此操作。我有很多类似的屏幕,我想以这种方式实现。
我可以想象WTforms也可能以某种方式解析复选框的“假”值,而不是在这些情况下选中复选框,但如果可能的话,我找不到任何文档。
我还考虑在结果页面上处理它,如果值为“falsy”,则从request.args集合中删除变量,但这也感觉很糟糕。
也许有另一种方法可以做到这一点,我不知道,或者我的解决方法只是用复选框处理重定向的方式,我不知道,但在我看来,这是一个很常见的用例,Flask-WTForms可能会有某种解决方案。
任何建议都将受到赞赏。
编辑:
问题更严重;我只是注意到使用以下代码将空字符串传递给我的重定向:
all_employees='y' if form.data['all_employees'] else ''
随后使用以下方式实例化和呈现表单:
form = SearchForm(request.args)
将空复选框渲染为:
<input id="include_inactive" name="include_inactive" type="checkbox" value="">
因此,之后再次检查它会将空字符串传递回Flask,因此当取消选中一个复选框时,它将在此之后呈现空值,并且永远不会再次检查它。
答案 0 :(得分:0)
在最基本的情况下,从HTML复选框的角度来看,urlencoded字符串otherdata=value&all_employees=False
是一个真正的值。
WTForms 主要是遵循HTML表单和表单数据的规则。但是,由于此布尔值是常见的烦恼,您可以使用false_values关键字参数自定义此值来定义'falsey'值...您可以false_values
包括字符串False
。
替代方式,更多'HTML spec friendly'将是这样的帮助:
def url_for_form(urlname, form, **kwargs):
for field in form:
if field.data: # would exclude blank strings too
kwargs[field.name] = field.data
return url_for(urlname, **kwargs)
用法就像url_for_form('blah.search', form, otherparam=9)
如果您需要选择特定字段,那么您可以稍微改变一下。