我正在尝试通过一种烧瓶形式对数据库模型进行多次更新。本质上,我想显示测试的问题,然后让用户输入测试的答案,然后获取所有单独的响应并更新下面列出的每个对应的db.Model。
我现在所拥有的是:
表格:
class InputStudentTestForm(flaskForm):
answer = StringField('Answer',validators=[DataRequired()])
submit = SubmitField('Submit Answers')
页面:
{% extends "base.html" %}
{% block content %}
<h1>{{ test.name }}</h1>
<form action="" method="post" >
{{ form.hidden_tag() }}
{% for q in questions %}
<p>
{{ q.text }} <br>
{{ form.answer }}
</p>
{% endfor %}
<p>
{{ form.submit() }}
</p>
</form>
{% endblock %}
路由:
@app.route('/input_answer/<testname>',methods=['GET','POST'])
def input_test_answer(testname):
test = Test.query.filter_by(name=testname).first_or_404()
questions = test.questions.all()
form = InputStudentTestForm()
if form.validate_on_submit():
i = 0
for value in form.data:
q = questions[i]
a = Student_Answers(current_user,test,q)
a.add_response(value)
db.session.add(a)
db.session.commit()
i = i + 1
flash('You have just added new test responses')
return redirect(url_for('index'))
return render_template('input_test_answers.html',test=test,questions=questions,form=form)
型号:
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',lazy='dynamic')
db.relationship('Question',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,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)
但是当用户提交数据时,我收到一个唯一的约束失败,因为Student_Answers正在使用参数(1,1,1'answer')更新。
我认为失败的原因是学生回答必须是单个字符,但是我不确定从form.data字符串'answer'的位置。任何帮助将是巨大的!谢谢。
编辑:我正在尝试实现动态表单方法,并出现UnboundField错误。这是更新的代码:
表格:
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 %}
但是在这一点上,我收到了UnboundField错误,但我不确定为什么。