add user marknig pages

This commit is contained in:
Ross
2026-01-04 12:39:33 +00:00
parent fa18c33e8a
commit 4ffadd3914
5 changed files with 183 additions and 1 deletions
+86
View File
@@ -12,6 +12,7 @@ from generic.views import (
RedirectMixin,
get_question_and_content_type,
get_user_exams,
get_exam_model_from_app_name,
)
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist
from django.shortcuts import render, get_object_or_404, redirect
@@ -266,6 +267,91 @@ def user_scores(request, user=None):
)
@login_required
def user_marking(request):
"""Main page for user marking overview. Uses HTMX to fetch per-app partials."""
apps = ["physics", "anatomy", "rapids", "shorts", "longs", "sbas"]
return render(request, "rad/user_marking.html", {"apps": apps})
@login_required
def user_marking_partial(request, exam_type: str):
"""Return an HTMX partial listing exams the user can mark for a given exam type.
Each exam is checked for whether it has any unmarked answers (using
question.get_unmarked_user_answer_count when available).
"""
user = request.user
try:
ExamModel = get_exam_model_from_app_name(exam_type)
except Exception:
return HttpResponse("Unknown exam type", status=400)
# Exams where user is an author or an authorised marker
exams_qs = ExamModel.objects.filter(
archive=False, exam_mode=True
).filter(Q(author=user) | Q(markers=user)).prefetch_related("author", "markers")
exams_data = []
for exam in exams_qs.order_by("name"):
has_unmarked = False
unmarked_count = 0
# iterate questions and use their helper to count unmarked answers when available
for q in exam.get_questions():
count = 0
# Prefer question-provided helper if present
helper = getattr(q, "get_unmarked_user_answer_count", None)
if callable(helper):
try:
count = helper(exam_pk=exam.pk, marker=user)
except TypeError:
count = helper(exam_pk=exam.pk)
except Exception:
count = 0
else:
# Fallback: inspect related answer manager if present
rel_manager = None
for rel_name in ("cid_user_answers", "user_answers", "answers", "useranswer_set"):
if hasattr(q, rel_name):
rel_manager = getattr(q, rel_name)
break
if rel_manager is not None:
try:
ans_model = rel_manager.model
# If the answer model has a `score` field, count answers that are unmarked
field_names = [f.name for f in ans_model._meta.get_fields()]
if "score" in field_names:
# Try to detect an UNMARKED constant on the model
unmarked_vals = [None, ""]
model_score_const = getattr(ans_model, "ScoreOptions", None) or getattr(ans_model, "MarkOptions", None)
if model_score_const is not None:
# attempt to use any UNMARKED attribute
unmarked_val = getattr(model_score_const, "UNMARKED", None)
if unmarked_val is not None:
unmarked_vals.append(unmarked_val)
count = rel_manager.filter(exam__id=exam.pk).filter(score__in=unmarked_vals).count()
else:
# No score field — likely auto-marked; treat as 0
count = 0
except Exception:
count = 0
try:
c = int(count)
except Exception:
c = 0
if c:
has_unmarked = True
unmarked_count += c
exams_data.append({"exam": exam, "has_unmarked": has_unmarked, "unmarked_count": unmarked_count})
return render(request, "generic/partials/user_marking_exam_list.html", {"exams_data": exams_data, "exam_type": exam_type})
def cid_scores(request, cid, passcode):
# exam = get_object_or_404(Exam, pk=pk)