revert last commit
This commit is contained in:
+17
-53
@@ -3044,12 +3044,7 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
cid: int | None = None,
|
||||
passcode: str | None = None,
|
||||
):
|
||||
# Prefetch related relations used during the active_exams check to
|
||||
# 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")
|
||||
)
|
||||
exams = self.Exam.objects.filter(archive=False)
|
||||
|
||||
active_exams = {"exams": []}
|
||||
|
||||
@@ -3061,52 +3056,22 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
return JsonResponse({"status": "invalid"}, status=401)
|
||||
|
||||
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:
|
||||
# Skip exams the user cannot see unless it's active
|
||||
if not (exam.active or self.check_user_access(request.user, exam.pk)):
|
||||
if exam.active or self.check_user_access(request.user, exam.pk):
|
||||
if exam.exam_mode and not exam.check_cid_user(
|
||||
cid, passcode, user=request.user, user_id=request.user.pk
|
||||
):
|
||||
continue
|
||||
|
||||
# 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
|
||||
if exam.json_creation_time:
|
||||
creation_time = exam.json_creation_time.isoformat()
|
||||
else:
|
||||
creation_time = "None"
|
||||
|
||||
# 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
|
||||
|
||||
creation_time = exam.json_creation_time.isoformat() if exam.json_creation_time else "None"
|
||||
|
||||
url = request.build_absolute_uri(exam.get_json_url(cid=cid, passcode=passcode))
|
||||
url = request.build_absolute_uri(
|
||||
exam.get_json_url(cid=cid, passcode=passcode)
|
||||
)
|
||||
# hacky
|
||||
if not based:
|
||||
url = url + "/unbased"
|
||||
|
||||
@@ -3121,15 +3086,14 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
"exam_mode": exam.exam_mode,
|
||||
}
|
||||
|
||||
# Avoid generating question JSON in this endpoint; return existing ids
|
||||
# to keep CPU usage low. Generation should be handled asynchronously
|
||||
# or on-demand by the request that needs it.
|
||||
if self.question_type == "long":
|
||||
h = {}
|
||||
for question in exam.exam_questions.all():
|
||||
h[question.pk] = getattr(question, "question_json_id", None)
|
||||
# Generate json if needed
|
||||
if question.json_creation_time is None:
|
||||
question.get_question_json()
|
||||
h[question.pk] = question.question_json_id
|
||||
obj["multi_question_json"] = h
|
||||
|
||||
active_exams["exams"].append(obj)
|
||||
|
||||
if json is False:
|
||||
|
||||
Reference in New Issue
Block a user