如何在Django模型中保存用户专属的测验答案?
解决方案:新增用户答题记录模型
这是个很常见的需求,我们可以通过新增一个专门的模型来记录用户-测验-问题-所选答案的关联关系,完美解决保存用户选项的问题。下面是具体实现步骤:
1. 定义用户答题记录模型
首先在你的models.py中添加这个模型,用来存储用户的答题轨迹:
from django.db import models from django.conf import settings class UserQuizResponse(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='quiz_responses') quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE, related_name='user_responses') question = models.ForeignKey(Quiz_Question, on_delete=models.CASCADE, related_name='user_answers') selected_answer = models.ForeignKey(Answer_Options, on_delete=models.CASCADE, related_name='selected_by_users') submitted_at = models.DateTimeField(auto_now_add=True) # 自动记录答题时间 class Meta: # 可选约束:如果不允许用户重复回答同一个问题,取消下面注释 # unique_together = ('user', 'question') pass def __str__(self): return f"{self.user.username} - {self.quiz.quiz_name} - {self.question.text}"
字段说明:
user:关联系统用户模型(用settings.AUTH_USER_MODEL是最佳实践,兼容自定义用户模型)quiz:关联对应的测验,方便后续批量查询用户对某个测验的所有回答question:关联具体问题,明确这条记录对应哪个题目selected_answer:保存用户最终选择的答案submitted_at:自动记录答题时间,方便追踪用户的答题历史
2. 保存用户选择的代码实现
假设你有一个处理答题提交的视图,可以这样创建或更新用户的答题记录:
from django.shortcuts import get_object_or_404, redirect from .models import Quiz_Question, UserQuizResponse def submit_answer(request, question_id): if request.method == 'POST': question = get_object_or_404(Quiz_Question, id=question_id) selected_answer_id = request.POST.get('selected_answer') selected_answer = get_object_or_404(Answer_Options, id=selected_answer_id) # 验证所选答案是否属于当前问题的可选答案(避免无效数据) if selected_answer not in question.possible_answers.all(): # 这里可以返回错误提示,比如跳回答题页并显示错误 return redirect('quiz_question', question_id=question_id) # 创建或更新用户的答题记录 response, created = UserQuizResponse.objects.get_or_create( user=request.user, question=question, defaults={ 'quiz': question.quiz, 'selected_answer': selected_answer } ) # 如果是用户重新答题,更新所选答案 if not created: response.selected_answer = selected_answer response.save() # 这里可以跳转到下一题或结果页 return redirect('next_question')
3. 统计用户测验得分示例
如果需要计算用户某个测验的得分,可以用以下逻辑:
def get_quiz_score(user, quiz): user_responses = UserQuizResponse.objects.filter(user=user, quiz=quiz) total_questions = quiz.questions.count() correct_count = 0 for response in user_responses: if response.selected_answer == response.question.correct: correct_count += 1 return { 'total': total_questions, 'correct': correct_count, 'score': round((correct_count / total_questions) * 100, 2) if total_questions > 0 else 0 }
额外提示
- 如果允许用户多次参加同一测验,可以去掉
unique_together约束,或者改成('user', 'quiz', 'question'),这样用户可以多次答题,通过submitted_at区分不同的答题记录。 - 前端提交表单时,建议把问题ID和所选答案ID作为表单字段传递,方便后端处理。
内容的提问来源于stack exchange,提问作者Shashishekhar Hasabnis
相关产品推荐
相关产品推荐

