简体   繁体   English

Flask-WTForms form.validate()在动态选择上失败

[英]Flask-WTForms form.validate() fails on dynamic choices

I'm creating a survey application that displays the survey question and choices and allows the user to pick a choice through the Flask-WTForms package. 我正在创建一个显示调查问题和选择的调查应用程序,并允许用户通过Flask-WTForms包选择一个选项。 The form uses a RadioField and seems to fail form.validate() when populating the choices attribute dynamically. 该表单使用RadioField并且在动态填充choices属性时似乎会失败form.validate()

When I manually enter in the choices as such: 当我手动输入以下选项时:

class SurveyAnswerForm(FlaskForm):
    answers = RadioField('Answers',
                         coerce=str,
                         choices=[('18-25', '18-25'), ('26-35', '26-35')])

form.validate() returns True and there are no errors in form.error . form.validate()返回True,并且form.error中没有错误。

When I decide to populate the choices attribute dynamically (see below), form.validate() returns False and form.error returns: 当我决定动态填充choices属性时(请参见下文), form.validate()返回False,form.error返回:

{'answers': ['Not a valid choice']}. {'答案':['无效的选择']}。

I've been working at this for hours and am not sure why form.validate() returns False . 我已经为此工作了几个小时,并且不确定为什么form.validate()返回False

forms.py : form.py

from flask_wtf import FlaskForm
from wtforms import RadioField

class SurveyAnswerForm(FlaskForm):
    answers = RadioField('Answers',
                         coerce=str,
                         choices=[])

app.py : app.py

@app.route('/survey/<int:survey_id>/questions', methods=['GET', 'POST'])
def survey_questions(survey_id):
    survey = Survey.query.filter_by(id=survey_id).first()
    page = request.args.get('page', 1, type=int)
    questions = SurveyQuestion.query.filter_by(survey_id=survey_id)\
        .order_by(SurveyQuestion.id)\
        .paginate(page, 1, True)

    for question in questions.items:
        question_id = question.id

    choices = QuestionChoices.query\
        .join(SurveyQuestion,
              and_(QuestionChoices.question_id==question_id,
               SurveyQuestion.survey_id==survey_id)).all()

    form = SurveyAnswerForm(request.form)
    form.answers.choices = [(choice.choice, choice.choice)\
        for choice in choices]

    if request.method =='POST' and form.validate():
        print('Successful POST')

    next_url = url_for('survey_questions', survey_id=survey.id,
                       page=questions.next_num)\
        if questions.has_next else None
    prev_url = url_for('survey_questions', survey_id=survey.id,
                   page=questions.prev_num)\
        if questions.has_prev else None

    return render_template('survey_question.html',
                           survey=survey,
                           questions=questions.items,
                           choices=choices,
                           form=form,
                           next_url=next_url, prev_url=prev_url)

survey_question.html : survey_question.html

{% extends "layout.html" %}
{% block body %}
  <h2>{{ survey.survey_title }}</h2>
  {% for question in questions %}
    <h3>{{ question.question }}</h3>
  {% endfor %}

  <form action="{{ next_url }}" method="POST">
    {{ form.csrf_token }}
    {{ form.answers(name='answer') }}

    {% if prev_url %}
      <a href="{{ prev_url }}">Back</a>
    {% endif %}
    {% if next_url %}
      <input type="submit" value="Continue">
   {% else %}
      <a href="#">Finish</a>
    {% endif %}
  </form>
{% endblock %}

The problem was submitting a POST request with pagination. 问题是通过分页提交POST请求。 if the current link is /survey/1/question?page=2 the form will submit to /submit/1/question?page=3 . 如果当前链接为/survey/1/question?page=2则表单将提交给/submit/1/question?page=3 To remedy this, I just created a separate route for submission and handled logic there. 为了解决这个问题,我只是创建了一条单独的提交路径并在那里处理了逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM