Add AddExamForm and update exam_edit_fragment for exam management
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
{% load static %}
|
||||
<div id="exam-list">
|
||||
<form hx-post="{% url 'anatomy:question_add_exam' question_id=question.pk %}" hx-target="#exam-list" hx-swap="innerHTML">
|
||||
{% csrf_token %}
|
||||
<div class="input-group mb-2">
|
||||
{{ form.exam }}
|
||||
<button class="btn btn-sm btn-primary" type="submit">Add</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="document.getElementById('exam-list').innerHTML='';">Close</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="mb-2 small">Current exams:
|
||||
{% for exam in question.exams.all %}
|
||||
<form class="d-inline me-1" hx-post="{% url 'anatomy:question_add_exam' question_id=question.pk %}" hx-target="#exam-list" hx-swap="innerHTML">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="exam_id" value="{{ exam.id }}">
|
||||
<input type="hidden" name="remove" value="true">
|
||||
<button class="btn btn-sm btn-outline-danger mb-1" type="submit" hx-confirm="Are you sure you want to remove this exam?">{{ exam }}</button>
|
||||
</form>
|
||||
{% empty %}
|
||||
<span class="text-muted">No exams</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
+42
-32
@@ -59,6 +59,21 @@ from .models import (
|
||||
# HalfMarkAnswers,
|
||||
# IncorrectAnswers,
|
||||
)
|
||||
from generic.widgets import ExamSearchWidget
|
||||
|
||||
|
||||
class AddExamForm(forms.Form):
|
||||
exam = forms.ModelChoiceField(queryset=Exam.objects.none(), required=True, widget=ExamSearchWidget(exam_model=Exam), label="Exam to add")
|
||||
|
||||
def __init__(self, *args, user=None, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
if user is None:
|
||||
qs = Exam.objects.none()
|
||||
elif user.groups.filter(name="anatomy_checker").exists():
|
||||
qs = Exam.objects.all()
|
||||
else:
|
||||
qs = Exam.objects.filter(author__id=user.id) | Exam.objects.filter(open_access=True)
|
||||
self.fields["exam"].queryset = qs.distinct()
|
||||
from generic.models import CidUser, Examination
|
||||
from generic.views import AuthorRequiredMixin, ExamCloneMixin, ExamCreateBase, ExamDeleteBase, ExamGroupsUpdateBase, ExamUpdateBase, ExamViews, GenericViewBase, UpdateQuestionMixin
|
||||
from reversion.views import RevisionMixin
|
||||
@@ -1627,44 +1642,39 @@ def question_add_exam(request, question_id: int):
|
||||
return HttpResponse("Invalid permissions", status=403)
|
||||
|
||||
|
||||
if request.POST:
|
||||
# POST: handle add/remove; if exam_id provided use existing behaviour
|
||||
if request.method == "POST":
|
||||
exam_id = request.POST.get("exam_id", None)
|
||||
|
||||
if exam_id is None:
|
||||
return HttpResponse("No exam id provided", status=400)
|
||||
if exam_id:
|
||||
exam = get_object_or_404(Exam, pk=exam_id)
|
||||
if request.POST.get("remove", False) == "true":
|
||||
question.exams.remove(exam)
|
||||
else:
|
||||
question.exams.add(exam)
|
||||
|
||||
exam = get_object_or_404(Exam, pk=exam_id)
|
||||
# return updated fragment
|
||||
form = AddExamForm(user=request.user)
|
||||
return render(request, "anatomy/partials/exam_edit_fragment.html", {"form": form, "question": question})
|
||||
|
||||
if request.POST.get("remove", False) == "true":
|
||||
question.exams.remove(exam)
|
||||
return HttpResponse("Question removed from exam.")
|
||||
# else try to process from the search form
|
||||
form = AddExamForm(request.POST, user=request.user)
|
||||
if form.is_valid():
|
||||
exam = form.cleaned_data.get("exam")
|
||||
if request.POST.get("remove", False) == "true":
|
||||
question.exams.remove(exam)
|
||||
else:
|
||||
question.exams.add(exam)
|
||||
|
||||
form = AddExamForm(user=request.user)
|
||||
return render(request, "anatomy/partials/exam_edit_fragment.html", {"form": form, "question": question})
|
||||
else:
|
||||
question.exams.add(exam)
|
||||
# render form with errors
|
||||
return render(request, "anatomy/partials/exam_edit_fragment.html", {"form": form, "question": question})
|
||||
|
||||
return HttpResponse("Question added to exam.")
|
||||
else:
|
||||
# Return a list of exams that we can add to the question
|
||||
|
||||
exams = Exam.objects.filter(author=request.user)
|
||||
exams = exams.difference(question.exams.all())
|
||||
|
||||
if not exams:
|
||||
return HttpResponse("No exams available to add")
|
||||
|
||||
html = "Exams to add to question: <br>"
|
||||
for exam in exams:
|
||||
html = html + (f"<span id='htmx-exam-list'><form><input name='exam_id' value='{exam.id}' type='hidden'><button hx-post=\"{request.path}\""
|
||||
f">{exam.name}: {exam.id}</button></form>"
|
||||
)
|
||||
html = html + "<br>Exams to remove from question: <br>"
|
||||
for exam in question.exams.all():
|
||||
html = html + (f"<span id='htmx-exam-list'><form><input name='exam_id' value='{exam.id}' type='hidden'><input name='remove' value='true' type='hidden'><button hx-post=\"{request.path}\""
|
||||
f"hx-confirm='Are you sure you want to remove this exam from the question?'"
|
||||
f">{exam.name}: {exam.id}</button></form>"
|
||||
)
|
||||
html = html + "<button _='on click remove #htmx-exam-list'>Cancel</button>"
|
||||
|
||||
return HttpResponse(mark_safe(html))
|
||||
# GET: render the fragment with the add form and current exams
|
||||
form = AddExamForm(user=request.user)
|
||||
return render(request, "anatomy/partials/exam_edit_fragment.html", {"form": form, "question": question})
|
||||
|
||||
|
||||
raise PermissionDenied()
|
||||
|
||||
Reference in New Issue
Block a user