Django遍历问卷答案按权重计算总分实现方法
Django问卷系统计分逻辑修正方案
问题背景
现有问卷系统计分规则为:
- 单题得分 = 所选答案的分值 * 答案对应权重
- 问卷总分 = 所有已作答题目的单题得分累加
原代码存在逻辑错误:将count()返回的已答题数整数值作为可遍历的答案集合,无法完成计分计算。
修正后的视图代码
questionnaires = ProjectQuestionnaire.objects.all() results = [] for q in questionnaires: # 优化查询:用first()替代exists()+get(),减少一次数据库查询 q_response = ProjectQuestionnaireResponse.objects.filter( project_name_id=project_id, questionnaire_id=q.id ).first() if not q_response: continue # 先获取当前问卷响应下所有有效(非空答案)的答题记录集合,预加载关联数据减少查询次数 valid_answers = ProjectQuestionnaireAnswer.objects.filter( response=q_response, answer__isnull=False ).select_related('answer') q_answered_count = valid_answers.count() # 计算答题完成度 total_question_count = ProjectQuestionnaireQuestion.objects.filter(questionnaire_id=q.id).count() if q_answered_count > 1 and total_question_count > 0: q_count = 100 / total_question_count * q_answered_count else: q_count = 0 ###### 计分逻辑START ###### total_score = 0 for ans in valid_answers: # 读取选项分值:choice_value是字符串类型,转成整数,空值/非数字值默认按0处理 try: choice_score = int(ans.answer.choice_value) if ans.answer.choice_value else 0 except (ValueError, TypeError): choice_score = 0 # 读取选项权重:空值默认按0处理 choice_weight = ans.answer.choice_weight if ans.answer.choice_weight is not None else 0 # 累加单题得分 total_score += choice_score * choice_weight ###### 计分逻辑END ###### # 可根据业务需要将计算结果存入results results.append({ "questionnaire": q, "complete_rate": q_count, "total_score": total_score })
关键修改说明
- 修复遍历错误:不再对计数返回的整数做循环,先查询得到有效答案的
QuerySet集合再遍历 - 性能优化:使用
select_related预加载答案关联的选项数据,避免循环内重复发起数据库查询;简化响应查询逻辑,减少冗余DB请求 - 兼容性处理:对字符串类型的分值字段做类型转换,增加空值、非法值兜底逻辑,避免格式异常导致程序报错
- 严格匹配规则:完全按照「单题分值*权重后累加」的规则计算总分,和给定计算示例逻辑一致
内容的提问来源于stack exchange,提问作者JacksWastedLife
相关产品推荐
相关产品推荐

