revert last commit

This commit is contained in:
Ross
2026-01-04 13:19:36 +00:00
parent 429adfc376
commit c0c12ea9f9
+34 -70
View File
@@ -3044,12 +3044,7 @@ class ExamViews(View, LoginRequiredMixin):
cid: int | None = None, cid: int | None = None,
passcode: str | None = None, passcode: str | None = None,
): ):
# Prefetch related relations used during the active_exams check to exams = self.Exam.objects.filter(archive=False)
# avoid N+1 queries when iterating many exams.
exams = (
self.Exam.objects.filter(archive=False)
.prefetch_related("valid_cid_users", "valid_user_users", "exam_questions")
)
active_exams = {"exams": []} active_exams = {"exams": []}
@@ -3061,76 +3056,45 @@ class ExamViews(View, LoginRequiredMixin):
return JsonResponse({"status": "invalid"}, status=401) return JsonResponse({"status": "invalid"}, status=401)
exam: ExamBase exam: ExamBase
# Prepare cid/user quick lookup when cid/user provided to avoid DB hits
user_id = request.user.pk if hasattr(request, "user") and request.user.is_authenticated else None
for exam in exams: for exam in exams:
# Skip exams the user cannot see unless it's active if exam.active or self.check_user_access(request.user, exam.pk):
if not (exam.active or self.check_user_access(request.user, exam.pk)): if exam.exam_mode and not exam.check_cid_user(
continue cid, passcode, user=request.user, user_id=request.user.pk
):
# If exam is in exam_mode, ensure the cid/user is allowed. Use the
# prefetched relations to perform in-memory checks rather than extra
# DB queries via `check_cid_user` which issues its own queries.
if exam.exam_mode:
allowed = False
# superusers always allowed
if hasattr(request, "user") and getattr(request.user, "is_superuser", False):
allowed = True
# open access allows any logged-in user
if not allowed and exam.exam_open_access and user_id is not None:
allowed = True
# check valid_user_users (prefetched)
if not allowed and user_id is not None:
try:
valid_user_ids = {u.pk for u in exam.valid_user_users.all()}
if user_id in valid_user_ids:
allowed = True
except Exception:
allowed = False
# check CID users when cid provided
if not allowed and cid is not None:
try:
for cu in exam.valid_cid_users.all():
if getattr(cu, "cid", None) == cid and getattr(cu, "passcode", None) == passcode:
allowed = True
break
except Exception:
allowed = False
if not allowed:
continue continue
creation_time = exam.json_creation_time.isoformat() if exam.json_creation_time else "None" if exam.json_creation_time:
creation_time = exam.json_creation_time.isoformat()
else:
creation_time = "None"
url = request.build_absolute_uri(exam.get_json_url(cid=cid, passcode=passcode)) url = request.build_absolute_uri(
if not based: exam.get_json_url(cid=cid, passcode=passcode)
url = url + "/unbased" )
# hacky
if not based:
url = url + "/unbased"
obj = { obj = {
"name": exam.get_exam_name(), "name": exam.get_exam_name(),
"url": url, "url": url,
"type": self.question_type, "type": self.question_type,
"eid": "{}/{}".format(self.question_type, exam.pk), "eid": "{}/{}".format(self.question_type, exam.pk),
"json_creation_time": creation_time, "json_creation_time": creation_time,
"exam_json_id": exam.exam_json_id, "exam_json_id": exam.exam_json_id,
"exam_active": exam.active, "exam_active": exam.active,
"exam_mode": exam.exam_mode, "exam_mode": exam.exam_mode,
} }
# Avoid generating question JSON in this endpoint; return existing ids if self.question_type == "long":
# to keep CPU usage low. Generation should be handled asynchronously h = {}
# or on-demand by the request that needs it. for question in exam.exam_questions.all():
if self.question_type == "long": # Generate json if needed
h = {} if question.json_creation_time is None:
for question in exam.exam_questions.all(): question.get_question_json()
h[question.pk] = getattr(question, "question_json_id", None) h[question.pk] = question.question_json_id
obj["multi_question_json"] = h obj["multi_question_json"] = h
active_exams["exams"].append(obj)
active_exams["exams"].append(obj)
if json is False: if json is False:
return active_exams["exams"] return active_exams["exams"]