diff --git a/anatomy/templates/anatomy/exams.html b/anatomy/templates/anatomy/exams.html
index 9bf8024a..c34a76a3 100644
--- a/anatomy/templates/anatomy/exams.html
+++ b/anatomy/templates/anatomy/exams.html
@@ -11,5 +11,6 @@
Candidates /
Stats /
{% endif %}
+ Review
{% comment %} Add New Question {% endcomment %}
{% endblock %}
diff --git a/atlas/templates/atlas/exams.html b/atlas/templates/atlas/exams.html
index 56941aac..4106e96d 100644
--- a/atlas/templates/atlas/exams.html
+++ b/atlas/templates/atlas/exams.html
@@ -7,7 +7,9 @@
{% if collection %}
{% include "atlas/collection_headers.html" %}
{% endif %}
-
+ {% if exam %}
+ Review /
+ {% endif %}
{% comment %} Collection: {{collection.name}}-> Overview /
Mark /
Scores /
diff --git a/generic/views.py b/generic/views.py
index c96acb18..9c308e87 100644
--- a/generic/views.py
+++ b/generic/views.py
@@ -3223,6 +3223,61 @@ 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'
diff --git a/longs/templates/longs/exams.html b/longs/templates/longs/exams.html
index 2c8d208d..235acbeb 100644
--- a/longs/templates/longs/exams.html
+++ b/longs/templates/longs/exams.html
@@ -9,4 +9,5 @@
Scores /
Candidates /
Stats /
+ Review /
{% endblock %}
diff --git a/physics/templates/physics/exams.html b/physics/templates/physics/exams.html
index 91d7471a..d3a8e274 100644
--- a/physics/templates/physics/exams.html
+++ b/physics/templates/physics/exams.html
@@ -7,4 +7,5 @@ Exams: {{exam}}-> Overvie
Scores /
Candidates /
Stats /
+ Review /
{% endblock %}
\ No newline at end of file
diff --git a/rapids/templates/rapids/exams.html b/rapids/templates/rapids/exams.html
index b4b994ab..ec8feaeb 100644
--- a/rapids/templates/rapids/exams.html
+++ b/rapids/templates/rapids/exams.html
@@ -12,4 +12,5 @@
Stats /
{% endif %}
Add New Question
+ Review
{% endblock %}
diff --git a/sbas/templates/sbas/exams.html b/sbas/templates/sbas/exams.html
index 8583f3ac..46630742 100644
--- a/sbas/templates/sbas/exams.html
+++ b/sbas/templates/sbas/exams.html
@@ -8,4 +8,5 @@
Scores /
Candidates /
Stats /
+ Review /
{% endblock %}
diff --git a/shorts/templates/shorts/exams.html b/shorts/templates/shorts/exams.html
index ad7c880a..2d0a7a97 100644
--- a/shorts/templates/shorts/exams.html
+++ b/shorts/templates/shorts/exams.html
@@ -12,4 +12,5 @@
Stats /
{% endif %}
Add New Question
+ Review
{% endblock %}