我正在使用Flask和WTForms创建一个测验Webapp,其中向用户显示了一个他们可以回答的测验。测验的问题来自数据库,因此让用户回答测验的表格是动态的。表单类如下所示:
class QuizForm(FlaskForm):
answers = FieldList(RadioField('Correct Answer', choices=CHOICES,
validators=[DataRequired()]),
min_entries=0)
submit = SubmitField('Submit your answers')
在提供表单之前,我将条目追加到字段列表中,如下所示:
questions = Question.query.all()
form = QuizForm()
for i, question in enumerate(questions):
form.answers.append_entry()
choices = [('1', question.option_a),
('2', question.option_b),
('3', question.option_c),
('4', question.option_d)]
form.answers.entries[i].choices = choices
这很好用,并且可以创建我期望的表格。但是,我无法在想要确保用户已回答所有问题的地方进行验证。这是我当前验证表单的方式:
questions = Question.query.all()
form = QuizForm(request.form)
if request.method == 'POST':
if form.validate() and len(form.answers.entries) == len(questions):
# use form data
我遇到的问题是:
form.validate()
进行验证。field.errors
的值,因此我无法向用户显示一条消息,要求在包含问题选项的单选字段正下方需要一个字段(使用WTForms验证)。完整代码可在github上看到。
对此用例实施验证的好方法是什么?
答案 0 :(得分:1)
如所评论的其他问题信息:stackoverflow.com/questions/50882720和stackoverflow.com/questions/51048153
我个人将使用动态表单方法为所需的每个RadioField
分配一个唯一的名称,以使结果类似于例如静态创建表单的情况:
class WebForm(FlaskForm):
q_1 = RadioField('Q 1', validators=[InputRequired()], ...)
q_2 = RadioField('Q 2', validators=[InputRequired()], ...)
然后验证器肯定会按要求工作。
如果我不认为您可以在名为answers
的FieldList上编写自己的验证器。这是一个自定义验证器的示例,该验证器捕获了一个应该捕获全名的输入字段,并且如果未检测到名称之间的空格,它将中断:
from wtforms.validators import ValidationError
class WebForm(FlaskForm):
fullname = StringField('Input full name', validators=[])
def validate_fullname(self, field):
if ' ' not in field.data:
raise ValidationError('Please give first and last name')
如果您在FieldList
上编写自己的验证器,则可能会循环浏览并检查每个验证器是否有一些数据,但是(我认为)更痛苦的方法是为什么我说了我这样做的首选方式。 / p>