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:
|
if user is None:
|
||||||
user = request.user
|
user = request.user
|
||||||
|
|
||||||
questions = (
|
# Load questions; prefetch 'answers' for apps that use them to avoid repeated DB hits
|
||||||
exam.get_questions()
|
questions_qs = exam.get_questions()
|
||||||
) # .prefetch_related("cid_user_answers", "answers")
|
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:
|
# Map question_id -> UserAnswer for O(1) lookup
|
||||||
# cid_user_answers_q_map[ans.question] = ans
|
user_answers_map = {ua.question_id: ua for ua in user_answers_qs}
|
||||||
|
|
||||||
answers_and_marks = []
|
answers_and_marks = []
|
||||||
answers_marks = []
|
answers_marks = []
|
||||||
answers = []
|
answers = []
|
||||||
|
|
||||||
for q in questions:
|
for q in questions:
|
||||||
# Get user answer
|
# Get user answer from the in-memory map (avoids N+1 queries)
|
||||||
if cid is not None:
|
user_answer = user_answers_map.get(q.pk)
|
||||||
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()
|
|
||||||
# user_answer = cid_user_answers_q_map[q]
|
# user_answer = cid_user_answers_q_map[q]
|
||||||
|
|
||||||
feedback = None
|
feedback = None
|
||||||
|
|||||||
Reference in New Issue
Block a user