Implement primary answer management with HTMX support, including form for selecting or creating answers and display templates

This commit is contained in:
Ross
2026-02-16 09:46:57 +00:00
parent ec03def164
commit 17d3b4206a
7 changed files with 165 additions and 3 deletions
+56 -1
View File
@@ -46,6 +46,7 @@ from .forms import (
AnatomyQuestionForm,
ExamForm,
SuggestIncorrectAnswerForm,
PrimaryAnswerForm,
)
from .models import (
AnatomyQuestion,
@@ -1655,4 +1656,58 @@ def question_add_exam(request, question_id: int):
return HttpResponse(mark_safe(html))
raise PermissionDenied()
raise PermissionDenied()
@login_required
def primary_answer_htmx(request, pk: int):
"""HTMX endpoint to render or update a question's primary answer.
GET: render the form for selecting/creating primary answer.
POST: create/select answer and set `question.primary_answer`, then
return the display fragment.
"""
if not request.htmx:
raise PermissionDenied()
question = get_object_or_404(AnatomyQuestion, pk=pk)
if not question.can_edit(request.user):
return HttpResponse("Invalid permissions", status=403)
if request.method == "POST":
form = PrimaryAnswerForm(request.POST, question=question)
if form.is_valid():
new_text = form.cleaned_data.get("new_answer", "").strip()
existing = form.cleaned_data.get("existing_answer", "")
if new_text:
# create a new Answer and mark it CORRECT
ans = Answer(question=question, answer=new_text, proposed=False, status=Answer.MarkOptions.CORRECT)
ans.save()
question.primary_answer = ans
question.save(update_fields=["primary_answer"])
elif existing:
try:
aid = int(existing)
ans = Answer.objects.get(pk=aid, question=question)
question.primary_answer = ans
question.save(update_fields=["primary_answer"])
except (ValueError, Answer.DoesNotExist):
return HttpResponse("Invalid answer choice", status=400)
# return display fragment
return render(request, "anatomy/partials/primary_answer_display.html", {"question": question})
else:
return HttpResponse("Invalid form", status=400)
# Handle cancel request to restore original state
if request.method == "GET" and request.GET.get("cancel"):
if question.primary_answer:
return render(request, "anatomy/partials/primary_answer_display.html", {"question": question})
else:
return render(request, "anatomy/partials/primary_answer_empty.html", {"question": question})
# GET - render form
form = PrimaryAnswerForm(question=question)
return render(request, "anatomy/partials/primary_answer_form.html", {"form": form, "question": question})