【问题标题】:validate_on_submit() fails when RadioButton choices are dynamically generated动态生成 RadioButton 选项时,validate_on_submit() 失败
【发布时间】:2017-09-24 14:51:55
【问题描述】:

我正在使用 Flask、Jinja、WTForms、SqlAlchemy 等创建类似测验的 Web 应用程序来学习语言。一旦用户通过成功完成存储在 JSON 文件中的所有级别完成这样的语言课程,我希望该应用程序为他提供练习模式,用户将随机选择关卡。

当我运行应用程序时,我可以看到使用随机级别的值生成的单选按钮,但是当我选择任何答案并提交时,form.validate_on_submit() 返回 False 并形成.errors 返回 {'practiceform': [u'Not a valid choice']}。当我将值硬编码到 currentLevel 变量时,它可以正常工作。

views.py

@user_blueprint.route('/courses/<course>/quiz/practice',methods=['GET','POST'])
@login_required
def practice(course):
    courseClass = class_for_name("project.models", course.capitalize())
    courses = courseClass.query.filter_by(email=current_user.email).first()
    maxLevel = courseClass.query.filter_by(email=current_user.email).first().get_maxLevel()
    currentLevel = randint(0, maxLevel-1) # If this value is hard-coded or fetched from db, it works correctly

    dic = generateQuestion(course, currentLevel)
    display = dic["display"]
    correct = dic["correct"]
    options = dic["options"]

    form = PracticeForm(request.form)
    form.practiceform.choices = [(option, option) for option in options]


    if form.validate_on_submit():
        practiceForm = form.practiceform.data

        if ((practiceForm == correct) and courses):
            # Do something
            flash("Nice job", 'success')
            return redirect(url_for('user.practice', course=course))

        else:
            # Do something else
            flash("Wrong answer", 'danger')
            return redirect(url_for('user.practice', course=course))

    return render_template('courses/practice.html', form=form, display=display)

forms.py

class PracticeForm(Form):

    practiceform = RadioField('practice')

practice.html

{% extends "_base.html" %}
{% block content %}

<form action='' method='POST' role='form'>
    <p>
        <!-- Tried put form.csrf, form.csrf_token, form.hidden_tag() here -->
        {{ form.practiceform() }}
    </p>
    <input type="submit" value="submit" />
</form>
{% endblock %}

那我错过了什么?假设硬编码级别 25 可以正常工作,或者数字 25 是在 randint 中随机生成的,有什么区别?

【问题讨论】:

    标签: python flask sqlalchemy jinja2 flask-wtforms


    【解决方案1】:

    我的猜测是 optionint,错误 WTForms 从 request.form 获取 str

    当数据从请求返回时,WTForms 会将其视为 string,除非您使用 wtforms.fields.*Field 构造函数的 coerce kwarg 明确指定类型:

    practiceform = RadioField('practice', coerce=int)
    

    【讨论】:

      【解决方案2】:

      所以我发现 randint() 导致了问题,因为在 GET 和 POST 操作上都调用了 practice(course) 方法,这导致大多数时候有两个不同的整数 -> 两种不同的形式。所以我重构了代码。保留了 GET 操作的实践(课程)方法,并创建了一个处理 POST 操作的新方法,这解决了问题。

      【讨论】:

        猜你喜欢
        • 2012-10-15
        • 1970-01-01
        • 2018-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-01
        • 1970-01-01
        相关资源
        最近更新 更多