Flask 验证错误 'NoneType is not iterable' 来自 FormFields 的 FormList 中的 RadioField?
Flask Validation Error 'NoneType is not iterable' from RadioField in FormList of FormFields?
我正在使用 FormFields 的 FormList 动态填充 Flask 中的表单,但由于验证函数的错误而不知所措。在这个表格上,用户提供一个条目名称,然后对于从数据库 table 查询的每个游戏,从 RadioField 中选择一个,并将他们对他们选择的信心排名 1-N。我已经使用硬编码的测试对验证进行了测试,并且我已经让下面的动态字段生成工作,但是当我尝试验证下面的内容时,它在使用 [=13] 迭代 games-#-pick
时失败了=].
我认为这是因为循环不断超出我的范围。在我的测试中,我在 games
中只有三个条目,所以 idx
是 0,1,2,我应该看到生成了三个 PickForms。当验证失败时,我看到 self.name
是 games-3-pick
,因此验证正在检查我的 FormList 中的 FormField,而不是我应该生成的。
我如何验证这一点?是 FormField 验证的问题,还是我如何动态 appending_entry()
到 FormList?
@bp.route('/pick', methods=['GET', 'POST'])
def pick():
games = Game.query.order_by(Game.game_date.asc()).all()
form = EntryForm()
for idx, g in enumerate(games):
form.games.append_entry()
form.games[idx].pick.label = g.bowl_name
form.games[idx].pick.choices = [('away', g.away), ('home', g.home)]
if form.validate_on_submit():
...database writes and redirect if validated...
class PickForm(FlaskForm):
pick = RadioField(validators=[DataRequired()])
weight = IntegerField('Weight', validators=[DataRequired()])
class EntryForm(FlaskForm):
name = StringField('Entry Name', validators=[DataRequired()])
games = FieldList(FormField(PickForm))
submit = SubmitField('Submit')
def validate(self):
if not super(EntryForm, self).validate():
return False
result = True
seen = set()
for pick in self.games:
if (pick.weight.data in seen and
pick.weight.data <= len(self.games)):
pick.errors.append('Please rank reach pick from 1 to {} with no repeats.'.format(len(self.games)))
result = False
else:
seen.add(pick.weight.data)
return result
我怀疑您没有正确访问 form.games。我认为你需要使用:form.games.entries
如文档中所述:https://wtforms.readthedocs.io/en/latest/fields.html#field-enclosures
抱歉格式不正确。我在手机上,但仍然想获得积分。
问题最终是我在 GET 和 POST 请求上将条目附加到 form.games
上,导致列表的大小是我想要的两倍,但上半部分未填充。在附加条目之前检查 form.games
的当前长度的更多逻辑解决了这个问题。这可能不是动态添加这些字段的最优雅的可能方式,但它现在可以工作,并且比我以前的方式要好得多!
我正在使用 FormFields 的 FormList 动态填充 Flask 中的表单,但由于验证函数的错误而不知所措。在这个表格上,用户提供一个条目名称,然后对于从数据库 table 查询的每个游戏,从 RadioField 中选择一个,并将他们对他们选择的信心排名 1-N。我已经使用硬编码的测试对验证进行了测试,并且我已经让下面的动态字段生成工作,但是当我尝试验证下面的内容时,它在使用 [=13] 迭代 games-#-pick
时失败了=].
我认为这是因为循环不断超出我的范围。在我的测试中,我在 games
中只有三个条目,所以 idx
是 0,1,2,我应该看到生成了三个 PickForms。当验证失败时,我看到 self.name
是 games-3-pick
,因此验证正在检查我的 FormList 中的 FormField,而不是我应该生成的。
我如何验证这一点?是 FormField 验证的问题,还是我如何动态 appending_entry()
到 FormList?
@bp.route('/pick', methods=['GET', 'POST'])
def pick():
games = Game.query.order_by(Game.game_date.asc()).all()
form = EntryForm()
for idx, g in enumerate(games):
form.games.append_entry()
form.games[idx].pick.label = g.bowl_name
form.games[idx].pick.choices = [('away', g.away), ('home', g.home)]
if form.validate_on_submit():
...database writes and redirect if validated...
class PickForm(FlaskForm):
pick = RadioField(validators=[DataRequired()])
weight = IntegerField('Weight', validators=[DataRequired()])
class EntryForm(FlaskForm):
name = StringField('Entry Name', validators=[DataRequired()])
games = FieldList(FormField(PickForm))
submit = SubmitField('Submit')
def validate(self):
if not super(EntryForm, self).validate():
return False
result = True
seen = set()
for pick in self.games:
if (pick.weight.data in seen and
pick.weight.data <= len(self.games)):
pick.errors.append('Please rank reach pick from 1 to {} with no repeats.'.format(len(self.games)))
result = False
else:
seen.add(pick.weight.data)
return result
我怀疑您没有正确访问 form.games。我认为你需要使用:form.games.entries
如文档中所述:https://wtforms.readthedocs.io/en/latest/fields.html#field-enclosures
抱歉格式不正确。我在手机上,但仍然想获得积分。
问题最终是我在 GET 和 POST 请求上将条目附加到 form.games
上,导致列表的大小是我想要的两倍,但上半部分未填充。在附加条目之前检查 form.games
的当前长度的更多逻辑解决了这个问题。这可能不是动态添加这些字段的最优雅的可能方式,但它现在可以工作,并且比我以前的方式要好得多!