Optimize question loading and user answer retrieval in ExamViews to reduce database queries
This commit is contained in:
+15
-14
@@ -3436,29 +3436,30 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
if user is None:
|
||||
user = request.user
|
||||
|
||||
questions = (
|
||||
exam.get_questions()
|
||||
) # .prefetch_related("cid_user_answers", "answers")
|
||||
# Load questions; prefetch 'answers' for apps that use them to avoid repeated DB hits
|
||||
questions_qs = exam.get_questions()
|
||||
if self.app_name not in ("physics",):
|
||||
questions_qs = questions_qs.prefetch_related("answers")
|
||||
|
||||
# cid_user_answers = list(UserAnswer.objects.filter(cid=cid, exam__id=pk).prefetch_related("question"))
|
||||
# Materialize questions list for iteration
|
||||
questions = list(questions_qs)
|
||||
|
||||
# cid_user_answers_q_map = {}
|
||||
# Fetch all relevant UserAnswer objects up-front to avoid per-question queries
|
||||
if cid is not None:
|
||||
user_answers_qs = self.UserAnswer.objects.filter(cid=cid, exam__id=pk).select_related("question")
|
||||
else:
|
||||
user_answers_qs = self.UserAnswer.objects.filter(user=user, exam__id=pk).select_related("question")
|
||||
|
||||
# for ans in cid_user_answers:
|
||||
# cid_user_answers_q_map[ans.question] = ans
|
||||
# Map question_id -> UserAnswer for O(1) lookup
|
||||
user_answers_map = {ua.question_id: ua for ua in user_answers_qs}
|
||||
|
||||
answers_and_marks = []
|
||||
answers_marks = []
|
||||
answers = []
|
||||
|
||||
for q in questions:
|
||||
# Get user answer
|
||||
if cid is not None:
|
||||
user_answer = q.cid_user_answers.filter(cid=cid, exam__id=pk).first()
|
||||
else:
|
||||
user_answer = q.cid_user_answers.filter(
|
||||
user=request.user, exam__id=pk
|
||||
).first()
|
||||
# Get user answer from the in-memory map (avoids N+1 queries)
|
||||
user_answer = user_answers_map.get(q.pk)
|
||||
# user_answer = cid_user_answers_q_map[q]
|
||||
|
||||
feedback = None
|
||||
|
||||
Reference in New Issue
Block a user