You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django测验系统答案不显示,寻求解决及逐题出题实现方案

Django测验系统问题修复与功能实现方案

一、修复答案无法展示的问题

问题根源

  1. 误用AnswersForm:这个表单是用于后台管理答案数据的ModelForm,完全不适合用户答题场景。
  2. 模板逻辑错误:form_main.question_id == question.id的判断不成立,表单没有question_id属性,也未关联对应问题的答案集合。
  3. 未正确获取问题对应的答案:没有利用外键的反向查询获取每个问题的答案列表。

代码修改

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 13:07:04