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
相关产品推荐
相关产品推荐

