【问题标题】:Python/Flask-WTF - How can I randomize the choices from dynamic RadioField?Python/Flask-WTF - 如何随机化动态 RadioField 的选择?
【发布时间】:2018-06-23 05:22:16
【问题描述】:

我正在寻找使用 python/flask/flask-wtf 构建多项选择测验。我成功地从数据库中提取随机问题以及随机选择作为可能的答案。我在模板页面上使用了一个 for 循环,它首先显示问题,然后显示可能的答案。

这是我的模板。

<div class="quote-block">
{% for quote in quotes %}
    {{ quote.line_text }}
    <form method="POST">
        {{ form.hidden_tag() }}
        {{ form.question }}
        <input type="submit">
    </form>
{% endfor %}
</div>

我的问题是每个问题的可能答案都是相同的,并且顺序相同。我明白为什么会这样。对 RadioField 选项的数据库查询只发生一次。然后为 for 循环的每个实例提取该查询的结果。

这是我的查看路线。

@app.route('/quiz/', methods=['POST', 'GET'])
def quiz():
    quotes = Quotes.query.order_by(func.rand()).limit(5)
    form = Quiz()
    form.question.choices = [(choice.speaker_id, choice.speaker) for choice in Characters.query.order_by(func.rand()).limit(4)]
    return render_template('television/quiz.html', form=form, quotes=quotes, options=options)

还有我的表格。

class Quiz(FlaskForm):
    question = RadioField('Label', choices=[])

就像我说的,所有这些都有效。我只是不知道如何为每个问题开始一个新的选择查询。任何帮助将不胜感激。谢谢!

【问题讨论】:

    标签: python flask-wtforms


    【解决方案1】:

    您可以尝试动态扩展您的 FlaskForm:

    def Quiz(number_of_questions):
        class _Quiz(FlaskForm):
            pass
        for n in range(number_of_questions):
            setattr(_Quiz, RadioField('Label', choices=[]), 'question_' + str(n))
        return _Quiz()
    

    现在您的表单对于每个问题都有一个 question_[n] 属性,因此您可以在 jijna2 中对其进行迭代:

    <div class="quote-block">
    <form method="POST">
    {{ form.hidden_tag() }}
    {% for q_num in range(n) %}
        {{ quotes[q_num].line_text }}
        {{ form['question_' + q_num|string }}
    {% endfor %}
    <input type="submit">
    </form>
    </div>
    

    【讨论】:

    • 感谢您抽出宝贵时间回答。我不确定我是否完全了解如何使用它。我的查看路线将如何变化?
    • 你有没有观察到你的view route只生成随机答案,不一定会在随机答案集合中生成正确答案,也不添加到表单的问题?
    • 是的,我知道这个问题并取得了一些进展。
    【解决方案2】:

    经过大量阅读和研究后,我意识到我试图做的太多太快了。所以我退后一步,构建了我想要做的事情,然后它终于走到了一起。当然,我在表单验证部分遇到了新问题,但我会将其包含在一个新问题中。

    我最大的障碍是我试图为 RadioField 拉随机选择选项。相反,我在数据库表中添加了三列,并在表中提供了选项。这样可以更轻松地通过一个查询来提取选项和问题。

    基本上,我在表单中的字段上运行一个 for 循环。如果该字段是 RadioField,它将对数据库运行查询并拉取随机行。然后,我在拉出的行上使用另一个 for 循环,并将不同的元素分配给 RadioField 的各个部分(标签、选择)。

    如果您知道执行此操作的更优雅的方法,我很想听听。但现在它可以工作了。

    我的表单和模板保持不变。但这是我的新路线视图。

        @app.route('/quiz/', methods=['GET', 'POST'])
        def quiz():
            form = Quiz()
            for field in form:
                if field.type != "RadioField":
                    continue
                else:
                    pulls = Quotes.query.order_by(func.rand()).limit(1)
                    for pull in pulls:
                        answer = pull.speaker
                        option_two = pull.option_two
                        option_three = pull.option_three
                        option_four = pull.option_four
                        question = pull.line_text
                        field.label = pull.line_text
                        field.choices = [(answer, answer), (option_two, option_two), (option_three, option_three), (option_four, option_four)]
                return redirect(url_for('you_passed'))
            return render_template('television/quiz.html', form=form)
    

    【讨论】:

      猜你喜欢
      • 2017-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-29
      • 2019-03-10
      • 1970-01-01
      相关资源
      最近更新 更多