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

Django开发测验应用如何输出表单实现带题目的测验创建?

Django测验应用实现方案

1. 修正表单逻辑(forms.py)

你当前的表单绑定的是Answer模型,完全不符合创建测验的需求,我们需要用Django内联表单集实现测验、问题、答案的联动创建:

from django import forms
from .models import Quiz, Question, Answer

# 测验基础表单
class QuizForm(forms.ModelForm):
    class Meta:
        model = Quiz
        fields = ['category', 'name', 'description', 'slug', 'roll_out']

# 问题内联表单集:绑定到Quiz,创建测验时可添加多个问题
QuestionFormSet = forms.inlineformset_factory(
    Quiz,
    Question,
    fields=['label', 'order'],
    extra=3, # 默认显示3个问题输入框,可自行调整
    can_delete=True
)

# 答案内联表单集:绑定到Question,创建问题时可添加多个答案
AnswerFormSet = forms.inlineformset_factory(
    Question,
    Answer,
    fields=['label', 'is_correct'],
    extra=4, # 默认每个问题显示4个答案输入框,可自行调整
    can_delete=True
)

2. 视图层调整

2.1 新增测验创建视图

from django.shortcuts import redirect, render, get_object_or_404
from .forms import QuizForm, QuestionFormSet, AnswerFormSet

def create_quiz(request):
    if request.method == 'POST':
        quiz_form = QuizForm(request.POST)
        if quiz_form.is_valid():
            quiz = quiz_form.save()
            question_formset = QuestionFormSet(request.POST, instance=quiz)
            if question_formset.is_valid():
                questions = question_formset.save()
                # 批量保存每个问题对应的答案
                for question in questions:
                    answer_formset = AnswerFormSet(request.POST, instance=question)
                    if answer_formset.is_valid():
                        answer_formset.save()
                # 保存完成跳转到测验详情页
                return redirect('quiz_detail', quiz_id=quiz.id)
    else:
        quiz_form = QuizForm()
        question_formset = QuestionFormSet()
    return render(request, 'quiz/create_quiz.html', {
        'quiz_form': quiz_form,
        'question_formset': question_formset,
        'AnswerFormSet': AnswerFormSet
    })

2.2 现有详情展示视图优化

你当前的QuizDetailView已经传入了quiz对象,无需大改,仅添加异常处理避免不存在的quiz_id报错即可:

from django.shortcuts import get_object_or_404
class QuizDetailView(TemplateView):
    template_name = 'quiz/quiz_detail.html'

    def get_context_data(self, **kwargs):
        quiz_id = kwargs['quiz_id']
        quiz = get_object_or_404(Quiz, id=quiz_id)
        return {
            'quiz': quiz
        }

3. 模板实现层级展示

3.1 测验详情页(quiz/quiz_detail.html)

直接利用模型的关联属性层级遍历即可,你设置的related_name可以直接调用关联数据:

<!-- 分类信息 -->
<h2>分类:{{ quiz.category.name }}</h2>
<!-- 测验信息 -->
<h1>测验:{{ quiz.name }}</h1>
<p>测验描述:{{ quiz.description }}</p>
<hr>
<!-- 问题列表 -->
{% for question in quiz.questions.all|dictsort:"order" %}
<div class="question-item">
    <h3>第{{ question.order }}题:{{ question.label }}</h3>
    <ul>
    <!-- 答案列表 -->
    {% for answer in question.answers.all %}
        <li>
            {{ answer.label }}
            {% if answer.is_correct %}
            <span style="color: green;">(正确答案)</span>
            {% endif %}
        </li>
    {% endfor %}
    </ul>
</div>
{% empty %}
<p>当前测验暂未添加问题</p>
{% endfor %}

3.2 测验创建页模板(quiz/create_quiz.html)

<form method="post">
    {% csrf_token %}
    {{ quiz_form.as_p }}
    <h3>问题设置</h3>
    {{ question_formset.management_form }}
    {% for q_form in question_formset %}
        <div class="question-form" style="margin: 20px 0;padding: 15px;border: 1px solid #eee;">
            {{ q_form.as_p }}
            <h4>答案设置</h4>
            {% with answer_formset=AnswerFormSet instance=q_form.instance %}
                {{ answer_formset.management_form }}
                {% for a_form in answer_formset %}
                    {{ a_form.as_p }}
                {% endfor %}
            {% endwith %}
        </div>
    {% endfor %}
    <button type="submit">保存测验</button>
</form>

可根据自己的UI需求调整表单渲染样式,不需要默认字段提示的可以自行拆解表单字段渲染

内容的提问来源于stack exchange,提问作者Kubat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 05:54:04