Add HTMX support for exam selection and update related templates and views

This commit is contained in:
Ross
2025-10-20 21:12:42 +01:00
parent d342e7e047
commit 66711f5c15
7 changed files with 103 additions and 25 deletions
+5
View File
@@ -34,6 +34,11 @@ urlpatterns = [
views.generic_exam_json_edit,
name="generic_exam_json_edit",
),
path(
"generic_exam_htmx",
views.generic_exam_htmx,
name="generic_exam_htmx",
),
path("bulk_delete_questions/", views.bulk_delete_questions, name="bulk_delete_questions"),
path(
"examination-autocomplete",
+57
View File
@@ -567,6 +567,63 @@ def generic_exam_json_edit(request):
return JsonResponse(data, status=400)
@login_required
def generic_exam_htmx(request):
"""HTMX-specific endpoint for selecting an exam and adding selected questions.
GET: returns the exam selection fragment (same as earlier partial)
POST: expects 'type' and checkbox list 'selection' (or selection[]) and 'exam_id'
adds selected question ids to the chosen exam and returns a small HTML fragment
or JSON suitable for HTMX swapping.
"""
if request.method == "GET":
question_type = request.GET.get("type")
if not question_type:
return HttpResponse("Missing type", status=400)
try:
Exam = get_exam_model_from_app_name(question_type)
except Exception:
return HttpResponse("Unknown type", status=400)
exams = Exam.objects.filter(archive=False, exam_mode=True).order_by("name")[:200]
return render(request, "generic/partials/exam_select_fragment.html", {"exams": exams, "type": question_type})
if request.method == "POST":
question_type = request.POST.get("type")
if not question_type:
return JsonResponse({"status": "error", "message": "missing type"}, status=400)
try:
Exam = get_exam_model_from_app_name(question_type)
except Exception:
return JsonResponse({"status": "error", "message": "unknown type"}, status=400)
exam = get_object_or_404(Exam, pk=request.POST.get("exam_id"))
# read checkbox selections
sel = request.POST.getlist("selection") or request.POST.getlist("selection[]")
question_ids = []
for s in sel:
try:
question_ids.append(int(s))
except Exception:
continue
add_count = 0
for i in question_ids:
if not exam.exam_questions.filter(pk=i).exists():
add_count += 1
exam.exam_questions.add(i)
if add_count > 0:
exam.save()
# return a small HTMX-friendly fragment summarising the result
return render(request, "generic/partials/exam_select_result.html", {"added": add_count, "exam": exam})
return HttpResponse(status=405)
class ExamViews(View, LoginRequiredMixin):
def __init__(
self,