From 2142749db6f903ec36ef1b15ad51b2545609782d Mon Sep 17 00:00:00 2001 From: Ross Date: Sun, 9 Nov 2025 21:36:22 +0000 Subject: [PATCH] Refactor exam review URLs and streamline HTMX request handling in views --- generic/urls.py | 20 +++++++-------- generic/views.py | 63 +----------------------------------------------- 2 files changed, 11 insertions(+), 72 deletions(-) diff --git a/generic/urls.py b/generic/urls.py index 7739ef80..1a026d02 100755 --- a/generic/urls.py +++ b/generic/urls.py @@ -315,16 +315,6 @@ def generic_view_urls(generic_views: GenericViewBase): generic_views.question_user_answers, name="question_user_answers", ), - path( - "exam//review/start", - generic_views.exam_review_start, - name="exam_review_start", - ), - path( - "exam//review/", - generic_views.exam_review_question, - name="exam_review_question", - ), path( "question//user_answers//str", generic_views.question_user_answers_by_compare, @@ -363,6 +353,16 @@ def generic_exam_urls(generic_exam_view: GenericExamViews): generic_exam_view.exam_question_detail, name="exam_question_detail", ), + path( + "exam//review/start", + generic_exam_view.exam_review_start, + name="exam_review_start", + ), + path( + "exam//review/", + generic_exam_view.exam_review_question, + name="exam_review_question", + ), # path( # "exam//question//answer/", # generic_exam_view.exam_question_user_answer, diff --git a/generic/views.py b/generic/views.py index 8bc5f1ed..b4a5b3de 100644 --- a/generic/views.py +++ b/generic/views.py @@ -1216,13 +1216,7 @@ class ExamViews(View, LoginRequiredMixin): "can_edit": self.check_user_edit_access(request.user, exam_id=pk), } - # If this is an HTMX request, return only the fragment so the client - # can swap it into the page. HTMX sets the `HX-Request` header; use - # request.headers (case-insensitive) where available and fall back to - # the META variant for older environments/proxies. - is_htmx = True if request.htmx.prompt is not None else False - - if is_htmx: + if request.htmx: return render(request, "generic/partials/exam_review_question_fragment.html", context) return render(request, "generic/exam_review_question.html", context) @@ -3284,61 +3278,6 @@ class GenericViewBase: return render(request, "generic/partials/question_reviews_list.html", {"question": question, "reviews": reviews, "app_name": self.app_name}) - @method_decorator(login_required) - def exam_review_start(self, request, pk): - """Start a per-question review for an exam. Redirects to the first question.""" - # Ensure the user can edit the exam (authors only) - if not self.check_user_edit_access(request.user, exam_id=pk): - raise PermissionDenied - - exam = get_object_or_404(self.exam_object, pk=pk) - - # Materialise ordered questions - questions = list(exam.get_questions()) - if not questions: - return render(request, "generic/exam_review_complete.html", {"exam": exam, "app_name": self.app_name}) - - # Render the first question - return self.exam_review_question(request, pk, q_index=0) - - @method_decorator(login_required) - def exam_review_question(self, request, pk, q_index=0): - """Render a single question from an exam for review with navigation.""" - if not self.check_user_edit_access(request.user, exam_id=pk): - raise PermissionDenied - - exam = get_object_or_404(self.exam_object, pk=pk) - - questions = list(exam.get_questions()) - total = len(questions) - - try: - q_index = int(q_index) - except Exception: - q_index = 0 - - if q_index < 0 or q_index >= total: - # Out of range — render complete - return render(request, "generic/exam_review_complete.html", {"exam": exam, "app_name": self.app_name}) - - question = questions[q_index] - - prev_index = q_index - 1 if q_index > 0 else None - next_index = q_index + 1 if q_index < total - 1 else None - - context = { - "exam": exam, - "question": question, - "q_index": q_index, - "total": total, - "prev_index": prev_index, - "next_index": next_index, - "app_name": self.app_name, - "can_edit": self.check_user_edit_access(request.user, exam_id=pk), - } - - return render(request, "generic/exam_review_question.html", context) - def question_review_start(self, request): # Prepare category choices if the question model exposes a FK named 'category'