Flask 循环烧瓶形式

Flask 循环烧瓶形式,flask,flask-sqlalchemy,flask-wtforms,Flask,Flask Sqlalchemy,Flask Wtforms,我试图通过一个flask表单对数据库模型进行多次更新。本质上,我希望显示测试的问题,然后让用户输入测试的答案,然后获取所有单独的回答并更新下面列出的每个对应的db.Model 我现在有以下资料: 表格: 第页: 路线: def input_test_answer(testname): test = Test.query.filter_by(name=testname).first_or_404() questions = test.questions.all() ques

我试图通过一个flask表单对数据库模型进行多次更新。本质上,我希望显示测试的问题,然后让用户输入测试的答案,然后获取所有单独的回答并更新下面列出的每个对应的db.Model

我现在有以下资料:

表格:

第页:

路线:

def input_test_answer(testname):
    test = Test.query.filter_by(name=testname).first_or_404()
    questions = test.questions.all()
    questions_as_field = {}
    for q in questions:
        p = field.SelectField('{}' .format(q.text), choices=[('A', 'A'), ('B', 'B'), ('C', 'C'), ('D', 'D')], validators=[DataRequired()])
        questions_as_field.update(p)

    form = DynamicTestForm(questions_as_field)
    if form.validate_on_submit():
        i = 0
        for value in form.data.values():
            a = Student_Answers.query.filter_by(user_id=current_user.id,test_id=test.id, question_id=q.id).one()
            if not a.is_response(str(value)):
                a.student_option = str(value)
            i = i + 1
        db.session.commit()
        flash('You have just added new test responses')
        return redirect(url_for('user', username=current_user.name))
和第页:

{% extends "base.html" %}

{% block content %}
  <h1>{{ test.name }}</h1>
  <form action="" method="post" >
    {{ form.hidden_tag() }}
      {% for field in form %}
      <p>
        {{ field.label }} <br>
        {{ field() }}
      </p>

      {% endfor %}
      <p>
        {{ form.submit() }}
      </p>
  </form>

{% endblock %}
{%extends“base.html”%}
{%block content%}
{{test.name}
{{form.hidden_tag()}}
{%形式的字段为%}

{{field.label}}
{{field()}}

{%endfor%} {{form.submit()}}

{%endblock%}

但在这一点上,我收到了一个UnboundField错误,我不太清楚为什么

使用动态表单方法,我会尝试以下方法:

def DynamicTestForm(questions, *args, **kwargs):
    class TestForm(FlaskForm):
        pass

    for name, value in questions.items():
        setattr(TestForm, name, value)

    return TestForm(*args, **kwargs)


questions = {
    'question_1': fields.StringField('Question 1', description='The quick brown fox jumps over which lazy animal?'),
    'question_2': fields.StringField('Question 2', description='How many gigawatts does it take to go Back to the Future?')
}

f = DynamicTestForm(questions)

您的表单只接受一个答案,但您正在尝试将其应用于多个问题。因此,如果有52个问题,那么表单中必须有52个答案?基本上,是的,但我不确定这里是否有适合您的现成解决方案。也许会有帮助。用您的问题初始化并为每个问题创建一个答案字段。对于字符串
答案
表单。数据
是一个
dict
,因此
用于表单中的值。数据:
迭代字典键(即表单字段名称)。尝试
获取form.data.values()中的值:
。我能够提取一些字符,所以我解决了字符串问题,但是我认为您是对的,我必须创建一个动态表单,但是我不知道表单的参数和类属性是什么。类似于测试中的问题数量?我试图通过将已生成的问题插入准SelectField生成器来导出您设计的问题,但现在得到了一个UnboundField错误(请参见编辑)。我是否应该从一个独特的、不同的目录初始化中为表单设置问题?对于初学者来说,您似乎不正确地更新了
questions\u as\u字段。你需要给每个问题一个答案。类似于
questions\u as\u field.update({q.id:p})
class Student_Answers(db.Model):

    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=True, primary_key=True)
    test_id = db.Column(db.Integer, db.ForeignKey('test.id'), primary_key=True)
    question_id = db.Column(db.Integer, db.ForeignKey('question.id'), primary_key=True)
    student_option = db.Column(db.String(1))

    db.UniqueConstraint('user_id', 'test_id', 'question_id')
    db.relationship('User', uselist=False, backref='student_answers', lazy='dynamic')
    db.relationship('Test', uselist=False, backref='student_answers', lazy='dynamic')
    db.relationship('Question', uselist=False, backref='student_answers', lazy='dynamic')

    def add_response(self, answer):
        if not self.is_response(answer):
            self.student_option = answer

    def remove_response(self,answer):
        if self.is_response(answer):
            self.student_option = ''

    def is_response(self, answer):
        return self.student_option == answer

    def __init__(self, user, test, question):
        self.user_id = user.id
        self.test_id = test.id
        self.question_id = question.id

    def __repr__(self):
        return '<Student_Answer {}>'.format(self.student_option)
def DynamicTestForm(questions, *args, **kwargs):
    class TestForm(FlaskForm):
        pass

    for name, value in questions.items():
        setattr(TestForm, name, value)

    return TestForm(*args, **kwargs)
def input_test_answer(testname):
    test = Test.query.filter_by(name=testname).first_or_404()
    questions = test.questions.all()
    questions_as_field = {}
    for q in questions:
        p = field.SelectField('{}' .format(q.text), choices=[('A', 'A'), ('B', 'B'), ('C', 'C'), ('D', 'D')], validators=[DataRequired()])
        questions_as_field.update(p)

    form = DynamicTestForm(questions_as_field)
    if form.validate_on_submit():
        i = 0
        for value in form.data.values():
            a = Student_Answers.query.filter_by(user_id=current_user.id,test_id=test.id, question_id=q.id).one()
            if not a.is_response(str(value)):
                a.student_option = str(value)
            i = i + 1
        db.session.commit()
        flash('You have just added new test responses')
        return redirect(url_for('user', username=current_user.name))
{% extends "base.html" %}

{% block content %}
  <h1>{{ test.name }}</h1>
  <form action="" method="post" >
    {{ form.hidden_tag() }}
      {% for field in form %}
      <p>
        {{ field.label }} <br>
        {{ field() }}
      </p>

      {% endfor %}
      <p>
        {{ form.submit() }}
      </p>
  </form>

{% endblock %}
def DynamicTestForm(questions, *args, **kwargs):
    class TestForm(FlaskForm):
        pass

    for name, value in questions.items():
        setattr(TestForm, name, value)

    return TestForm(*args, **kwargs)


questions = {
    'question_1': fields.StringField('Question 1', description='The quick brown fox jumps over which lazy animal?'),
    'question_2': fields.StringField('Question 2', description='How many gigawatts does it take to go Back to the Future?')
}

f = DynamicTestForm(questions)