如何实现仅首次答题计算XP,后续多次尝试仅统计得分?
优化Django测验系统以支持无限次尝试逻辑
核心需求:用户首次参与测验可获得XP,从第二次开始不管尝试多少次,只统计答对题数,不发放XP。原实现仅支持最多2次尝试,现在要改成支持无限次。
1. 调整ClassAttempt模型
原来的try_num字段大概率设置了choices=(1,2)来限制尝试次数,直接去掉这个限制,让它能存储任意正整数:
# models.py class ClassAttempt(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) class_quiz = models.ForeignKey(ClassQuiz, on_delete=models.CASCADE) try_num = models.IntegerField(default=1) # 移除choices限制,默认首次尝试为1 # 其他原有字段保持不变
2. 重写UserClassScore视图的尝试次数逻辑
原来的逻辑应该是只处理try_num=1和2的情况,现在改成自动递增尝试次数,且仅首次尝试发XP:
# views.py class UserClassScore(APIView): def post(self, request): user = request.user quiz_id = request.data.get('quiz_id') quiz = ClassQuiz.objects.get(id=quiz_id) # 获取用户该测验的最后一次尝试次数,生成新的尝试记录 last_attempt = ClassAttempt.objects.filter(user=user, class_quiz=quiz).order_by('-try_num').first() new_try_num = last_attempt.try_num + 1 if last_attempt else 1 current_attempt = ClassAttempt.objects.create( user=user, class_quiz=quiz, try_num=new_try_num ) # 统计答对题数并保存答题记录 questions_data = request.data.get('questions') correct_count = 0 for q_data in questions_data: question = ClassQuestion.objects.get(id=q_data['question_id']) is_correct = (q_data['answer'] == question.correct_answer) UserClassQuestionsRecord.objects.create( user=user, class_question=question, class_attempt=current_attempt, is_correct=is_correct ) if is_correct: correct_count += 1 # 仅首次尝试发放XP earned_xp = 0 if current_attempt.try_num == 1: earned_xp = correct_count * 10 # 这里按实际规则调整XP计算方式 user.xp += earned_xp user.save() return Response({ 'correct_count': correct_count, 'earned_xp': earned_xp, 'current_try_num': current_attempt.try_num })
3. 移除序列化器的次数限制
如果你的序列化器里对try_num加了验证(比如只允许1和2),直接删掉这些限制:
# serializers.py class ClassAttemptSerializer(serializers.ModelSerializer): class Meta: model = ClassAttempt fields = ['id', 'user', 'class_quiz', 'try_num'] # 删掉原有的validators或choices相关配置
关键逻辑说明
- 每次尝试都会创建新的
ClassAttempt记录,try_num基于用户该测验的最后一次尝试自动加1,没有次数上限 - XP发放只看
try_num是否为1,不管是第2次还是第N次尝试,都不会发XP - 所有尝试的答题记录都会完整保存到
UserClassQuestionsRecord,方便后续统计用户的历史答题情况
内容的提问来源于stack exchange,提问作者Riccardo
相关产品推荐
相关产品推荐

