Flask-WTF含FieldList子表单的表单无法通过验证问题
问题解决:Flask-WTF FieldList子表单提交验证失败
问题根源
你的子表单IngredientsForm继承自FlaskForm,而FlaskForm默认会自动添加CSRF验证字段。但模板渲染时仅处理了主表单的hidden_tag(),未渲染每个子表单的CSRF字段,导致提交时子表单的csrf_token为None,触发子表单CSRF验证失败。由于FieldList的子表单错误不会冒泡到主表单的errors字典中,所以看不到明确错误提示,但表单整体验证不通过。
解决方案
方案一:子表单改用基础Form类(推荐)
子表单无需CSRF验证,直接继承wtforms的Form类而非FlaskForm,避免自动生成CSRF字段:
from wtforms import Form, StringField, validators class IngredientsForm(Form): # 替换为Form而非FlaskForm ingredient_name = StringField("Ingredient", validators=[validators.DataRequired()]) class RecipeForm(FlaskForm): recipe_name = StringField("Recipe name", validators=[DataRequired()]) ingredients = FieldList(FormField(IngredientsForm), min_entries=2, max_entries=5) submit = SubmitField("Submit")
方案二:渲染子表单的CSRF字段
若必须让子表单继承FlaskForm,需在模板循环中渲染每个子表单的hidden_tag():
<h1>Enter recipe:</h1> <form action="/submit" method="POST"> {{ form.hidden_tag() }} <p> {{ form.recipe_name.label }} <br> {{ form.recipe_name() }} </p> <p> {{ form.ingredients.label }} <br> {% for ing in form.ingredients %} {{ ing.hidden_tag() }} <!-- 添加此行渲染子表单CSRF字段 --> {{ ing.ingredient_name.label }} {{ ing.ingredient_name() }} <br> {% endfor %} </p> <p> {{ form.submit() }} </p> </form>
修改验证效果
调整后重新提交表单,子表单的csrf_token不再为None,表单可正常通过validate_on_submit()验证。
内容的提问来源于stack exchange,提问作者Vaiterius
相关产品推荐
相关产品推荐

