wtforms使用FieldList嵌套SelectField提交后无法获取数据如何解决?
问题原因
- 手动修改了
SelectField的name属性,破坏了WTForms的自动命名规则。WTForms中FieldList嵌套FormField会自动生成格式为{FieldList名}-{索引}-{内部字段名}的name值(例如options-0-option),修改为自定义的option0后,WTForms解析表单数据时无法匹配到对应字段,无法将提交值填充到set_form.options中。 - 提交表单后初始化
SetForm时,既没有传入表单数据,也没有重建和渲染阶段完全一致的动态字段结构。WTForms不会自动保存上一次请求生成的动态字段,提交后需要先按照和渲染时完全相同的逻辑生成所有动态字段,再传入表单数据做解析。 append_entry时手动传入SingleForm()实例属于不必要操作,WTForms会自动根据绑定的表单类型创建实例,手动传入可能导致内部状态异常。
解决方法
1. 修正渲染阶段的动态字段生成逻辑
不要修改字段的name属性,仅调整label和choices即可:
set_form = SetForm() for idx, (k, v) in enumerate(dic_options.items()): # 无需传入SingleForm实例,WTForms会自动创建 entry = set_form.options.append_entry() entry.option.label = str(k) entry.option.choices = [''] + list(map(str, v))
2. 修正提交阶段的表单初始化逻辑
提交后先按照完全相同的逻辑重建动态字段,再传入request.form做验证:
# 提交后首先重建和渲染时结构完全一致的动态字段,dic_options需和渲染时的内容完全相同 set_form = SetForm(request.form) for idx, (k, v) in enumerate(dic_options.items()): entry = set_form.options.append_entry() entry.option.label = str(k) entry.option.choices = [''] + list(map(str, v)) # 验证通过后即可正常读取数据 if set_form.validate_on_submit(): for entry in set_form.options: # 此处即可拿到每个SelectField的提交值 print(entry.option.data)
注意:如果
dic_options会随请求变化,需要在渲染时将其结构存在session中,提交时取出还原,保证渲染和提交阶段的动态字段结构完全一致,否则仍会出现数据读取失败的问题。
内容的提问来源于stack exchange,提问作者aja228
相关产品推荐
相关产品推荐

