Implement bulk update and delete functionality for exams with HTMX support
This commit is contained in:
@@ -988,6 +988,117 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
)
|
||||
)
|
||||
|
||||
@method_decorator(login_required)
|
||||
def exam_bulk_update(self, request):
|
||||
"""HTMX endpoint to bulk-update exams (currently supports updating the date).
|
||||
|
||||
Expects POST with 'exam_ids' (multiple) and optional 'date' (YYYY-MM-DD).
|
||||
Returns the updated exam list partial.
|
||||
"""
|
||||
if request.method != "POST":
|
||||
return HttpResponse(status=405)
|
||||
|
||||
exam_ids = request.POST.getlist("exam_ids")
|
||||
date_str = request.POST.get("date", "")
|
||||
|
||||
# Parse date if provided
|
||||
new_date = None
|
||||
if date_str:
|
||||
try:
|
||||
from datetime import date as _date
|
||||
|
||||
new_date = _date.fromisoformat(date_str)
|
||||
except Exception:
|
||||
new_date = None
|
||||
|
||||
# Find the queryset for the current user as index() does
|
||||
if (
|
||||
request.user.is_superuser
|
||||
or (
|
||||
self.app_name == "rapids"
|
||||
and request.user.groups.filter(name="rapid_checker").exists()
|
||||
)
|
||||
or (
|
||||
self.app_name == "anatomy"
|
||||
and request.user.groups.filter(name="anatomy_checker").exists()
|
||||
)
|
||||
or (
|
||||
self.app_name == "longs"
|
||||
and request.user.groups.filter(name="long_checker").exists()
|
||||
)
|
||||
):
|
||||
exams_qs = self.Exam.objects.all()
|
||||
filter = self.ExtraExamFilter(request.GET, queryset=exams_qs)
|
||||
else:
|
||||
exams_qs = self.Exam.objects.filter(author__id=request.user.id) | self.Exam.objects.filter(open_access=True)
|
||||
filter = self.BasicExamFilter(request.GET, queryset=exams_qs)
|
||||
|
||||
# Apply changes
|
||||
for eid in exam_ids:
|
||||
try:
|
||||
exam = self.Exam.objects.get(pk=eid)
|
||||
except self.Exam.DoesNotExist:
|
||||
continue
|
||||
|
||||
if not self.check_user_edit_access(request.user, exam_id=exam.pk):
|
||||
# Skip exams the user cannot edit
|
||||
continue
|
||||
|
||||
if new_date is not None:
|
||||
exam.date = new_date
|
||||
exam.save()
|
||||
|
||||
return render(request, "generic/partials/_exam_list.html", {"filter": filter, "app_name": self.app_name})
|
||||
|
||||
@method_decorator(login_required)
|
||||
def exam_bulk_delete(self, request):
|
||||
"""HTMX endpoint to bulk-delete selected exams. Expects POST 'exam_ids'.
|
||||
|
||||
Returns the updated exam list partial.
|
||||
"""
|
||||
if request.method != "POST":
|
||||
return HttpResponse(status=405)
|
||||
|
||||
exam_ids = request.POST.getlist("exam_ids")
|
||||
|
||||
if (
|
||||
request.user.is_superuser
|
||||
or (
|
||||
self.app_name == "rapids"
|
||||
and request.user.groups.filter(name="rapid_checker").exists()
|
||||
)
|
||||
or (
|
||||
self.app_name == "anatomy"
|
||||
and request.user.groups.filter(name="anatomy_checker").exists()
|
||||
)
|
||||
or (
|
||||
self.app_name == "longs"
|
||||
and request.user.groups.filter(name="long_checker").exists()
|
||||
)
|
||||
):
|
||||
exams_qs = self.Exam.objects.all()
|
||||
filter = self.ExtraExamFilter(request.GET, queryset=exams_qs)
|
||||
else:
|
||||
exams_qs = self.Exam.objects.filter(author__id=request.user.id) | self.Exam.objects.filter(open_access=True)
|
||||
filter = self.BasicExamFilter(request.GET, queryset=exams_qs)
|
||||
|
||||
for eid in exam_ids:
|
||||
try:
|
||||
exam = self.Exam.objects.get(pk=eid)
|
||||
except self.Exam.DoesNotExist:
|
||||
continue
|
||||
|
||||
if not self.check_user_edit_access(request.user, exam_id=exam.pk):
|
||||
continue
|
||||
|
||||
try:
|
||||
exam.delete()
|
||||
except Exception:
|
||||
# ignore individual delete failures
|
||||
continue
|
||||
|
||||
return render(request, "generic/partials/_exam_list.html", {"filter": filter, "app_name": self.app_name})
|
||||
|
||||
@method_decorator(login_required)
|
||||
def exam_toggle_results_published(self, request, pk):
|
||||
if request.method == "POST":
|
||||
|
||||
Reference in New Issue
Block a user