【问题标题】:Flask-WTForms form.validate() fails on dynamic choicesFlask-WTForms form.validate() 在动态选择上失败
【发布时间】:2018-02-22 20:44:50
【问题描述】:

我正在创建一个调查应用程序,它显示调查问题和选项,并允许用户通过 Flask-WTForms 包选择一个选项。该表单使用RadioField,并且在动态填充choices 属性时似乎失败了form.validate()

当我手动输入选项时:

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

form.validate() 返回 True 并且form.error 中没有错误。

当我决定动态填充选择属性时(见下文),form.validate() 返回 False 并且 form.error 返回:

{'answers': ['Not a valid choice']}。

我已经为此工作了好几个小时,不知道为什么 form.validate() 返回 False

forms.py

from flask_wtf import FlaskForm
from wtforms import RadioField

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

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

{% 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 %}

【问题讨论】:

  • 您的代码中似乎没有提到form.validate()
  • 很抱歉。我编辑了代码以显示它将在哪里验证。 'Successful POST' 永远不会被打印出来。
  • 最终花了两个小时让烧瓶再次运行(通过调试模式大声喊叫),然后点击您的“survey_id”并丢失了survey_questions文件夹和内容。 ..还有那一刻!这对我来说太久远了......退出这个topic.GL。
  • github.com/laskeym/Flask_Survey.git设置环境变量FLASK_APP=app.pyFLASK_DEBUG=1然后运行flask run
  • 我似乎找到了问题所在。它与将表单提交到{{ next_url }} url 有关。我在没有分页的情况下重写了这个脚本,只提交到/survey/&lt;survey_id&gt;/questions 并且能够验证表单。当我使用分页并将表单提交到/survey/survey_id/questions?page=2 时,表单似乎会丢失或覆盖数据。

标签: python flask wtforms flask-wtforms


【解决方案1】:

问题是提交带有分页的 POST 请求。如果当前链接是/survey/1/question?page=2,表单将提交给/submit/1/question?page=3。为了解决这个问题,我刚刚创建了一个单独的提交路径并在那里处理逻辑。

【讨论】:

  • 你能告诉我你是怎么做到的吗?我真的被困在做同样的事情。我有 36 页,但每次我选择一页上的复选框然后更改页面时,它已经失去了该状态
猜你喜欢
  • 2018-04-05
  • 2012-10-12
  • 2020-07-15
  • 2015-04-22
  • 2019-07-23
  • 2021-05-15
  • 2020-01-18
  • 2020-02-27
  • 1970-01-01
相关资源
最近更新 更多