Django测验系统答案不显示,寻求解决及逐题出题实现方案
Django测验系统问题修复与功能实现方案
一、修复答案无法展示的问题
问题根源
- 误用
AnswersForm:这个表单是用于后台管理答案数据的ModelForm,完全不适合用户答题场景。 - 模板逻辑错误:
form_main.question_id == question.id的判断不成立,表单没有question_id属性,也未关联对应问题的答案集合。 - 未正确获取问题对应的答案:没有利用外键的反向查询获取每个问题的答案列表。
代码修改
1. 替换答题表单(forms.py)
删除原AnswersForm,新增专门用于用户答题的表单:
from django import forms from .models import answers class QuestionAnswerForm(forms.Form): def __init__(self, question, *args, **kwargs): super().__init__(*args, **kwargs) # 生成当前问题的选项列表 answer_options = [(ans.id, ans.answer) for ans in answers.objects.filter(question=question)] self.fields['selected_answer'] = forms.ChoiceField( choices=answer_options, widget=forms.RadioSelect, label='' )
2. 调整主视图逻辑(views.py)
修改main函数,适配单题展示与答案提交:
def main(request): test_id = cache.get('test_id') id_people = cache.get('id_people') if not test_id or not id_people: return redirect('first') # 初始化或获取用户的题目序列 if 'question_sequence' not in request.session: question_sequence = list(random_questions(test_id).values_list('pk', flat=True)) request.session['question_sequence'] = question_sequence request.session['current_index'] = 0 question_sequence = request.session['question_sequence'] current_index = request.session['current_index'] current_question = questions.objects.get(pk=question_sequence[current_index]) if question_sequence else None if request.method == 'POST': form = QuestionAnswerForm(current_question, request.POST) if form.is_valid(): selected_ans_id = form.cleaned_data['selected_answer'] # 判断答案是否正确并更新分数 if answers.objects.get(id=selected_ans_id).true_answer: person = people.objects.get(pk=id_people) person.correct_answer += 1 person.save() # 跳转下一题 request.session['current_index'] += 1 return redirect('main') else: form = QuestionAnswerForm(current_question) if current_question else None data = { 'current_question': current_question, 'form': form } return render(request, 'main/main_page.html', data)
3. 修正模板渲染(main.html)
简化模板,直接渲染当前问题和对应选项:
{% extends 'main/base_page.html' %} {% block title %} Тестирование {% endblock %} {% block article %} <article> {% if current_question %} <form method="post"> {% csrf_token %} <h2>{{ current_question.question }}</h2> {{ form.as_p }} <button type="submit">Далее</button> </form> {% else %} <p>无可用题目</p> {% endif %} </article> {% endblock %}
二、实现15道不重复题目+逐题分页功能
核心逻辑
用用户专属的session存储随机生成的15道题ID序列,以及当前答题的索引位置,每次提交答案后更新索引,直到完成所有题目。
代码修改
1. 调整随机题目函数(views.py)
改为抽取15道不重复题目:
def random_questions(test_id): # 获取对应测试的所有题目ID all_question_ids = list(questions.objects.filter(test_id=test_id).values_list('pk', flat=True)) # 如果题目不足15道,返回全部;否则随机抽15道 if len(all_question_ids) <= 15: selected_ids = all_question_ids else: selected_ids = random.sample(all_question_ids, 15) return questions.objects.filter(pk__in=selected_ids)
2. 完善主视图分页逻辑(views.py)
更新main函数,处理答题进度与结束判断:
def main(request): id_people = cache.get('id_people') test_id = cache.get('test_id') if not id_people or not test_id: return redirect('first') # 初始化session中的答题数据 if 'question_sequence' not in request.session: # 生成15道随机题的ID列表 question_sequence = list(random_questions(test_id).values_list('pk', flat=True)) request.session['question_sequence'] = question_sequence request.session['current_index'] = 0 # 重置用户的正确答案数 people.objects.filter(pk=id_people).update(correct_answer=0) question_sequence = request.session['question_sequence'] current_index = request.session['current_index'] total_questions = len(question_sequence) # 判断是否完成所有题目 if current_index >= total_questions: # 更新用户测试完成状态 people.objects.filter(pk=id_people).update(done=True) # 根据得分跳转结果页(可自行调整及格线) person = people.objects.get(pk=id_people) return redirect('done') if person.correct_answer >= 10 else redirect('lose') # 获取当前要展示的题目 current_question = questions.objects.get(pk=question_sequence[current_index]) if request.method == 'POST': form = QuestionAnswerForm(current_question, request.POST) if form.is_valid(): selected_ans_id = form.cleaned_data['selected_answer'] # 验证答案正确性并更新分数 if answers.objects.get(id=selected_ans_id).true_answer: person = people.objects.get(pk=id_people) person.correct_answer += 1 person.save() # 推进到下一题 request.session['current_index'] = current_index + 1 return redirect('main') else: form = QuestionAnswerForm(current_question) data = { 'current_question': current_question, 'form': form, 'current_num': current_index + 1, 'total_num': total_questions } return render(request, 'main/main_page.html', data)
3. 模板添加进度提示(main.html)
在页面中显示当前答题进度:
{% extends 'main/base_page.html' %} {% block title %} Тестирование {% endblock %} {% block article %} <article> {% if current_question %} <p>进度:{{ current_num }} / {{ total_num }}</p> <form method="post"> {% csrf_token %} <h2>{{ current_question.question }}</h2> {{ form.as_p }} <button type="submit">Далее</button> </form> {% else %} <p>测试已完成</p> {% endif %} </article> {% endblock %}
内容的提问来源于stack exchange,提问作者Yan Shangareev
相关产品推荐
相关产品推荐

