Add merge category functionality for admin users with confirmation prompt
This commit is contained in:
@@ -1012,6 +1012,59 @@ def import_llm_questions(request):
|
||||
return JsonResponse({"ok": True, "report": report})
|
||||
|
||||
|
||||
@login_required
|
||||
@user_passes_test(lambda u: u.is_superuser)
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def merge_category(request):
|
||||
"""Admin view: merge one Category into another.
|
||||
|
||||
GET: render form to choose source and target categories.
|
||||
POST: expects 'source' and 'target' (category PKs) and optional 'delete_source' checkbox.
|
||||
The view will reassign all Question.category==source -> target and optionally delete the source Category.
|
||||
"""
|
||||
categories = Category.objects.all().order_by('category')
|
||||
|
||||
if request.method == 'GET':
|
||||
return render(request, 'sbas/merge_category.html', {'categories': categories})
|
||||
|
||||
# POST
|
||||
source_id = request.POST.get('source')
|
||||
target_id = request.POST.get('target')
|
||||
delete_source = request.POST.get('delete_source') in ('on', 'true', '1', 'True')
|
||||
|
||||
if not source_id or not target_id:
|
||||
return render(request, 'sbas/merge_category.html', {'categories': categories, 'error': 'Both source and target categories must be selected.'})
|
||||
|
||||
try:
|
||||
source = Category.objects.get(pk=int(source_id))
|
||||
target = Category.objects.get(pk=int(target_id))
|
||||
except Category.DoesNotExist:
|
||||
return render(request, 'sbas/merge_category.html', {'categories': categories, 'error': 'Invalid category selected.'})
|
||||
|
||||
if source.pk == target.pk:
|
||||
return render(request, 'sbas/merge_category.html', {'categories': categories, 'error': 'Source and target must be different.'})
|
||||
|
||||
# perform update inside a transaction
|
||||
from django.db import transaction
|
||||
|
||||
with transaction.atomic():
|
||||
qs = Question.objects.filter(category=source)
|
||||
count = qs.count()
|
||||
qs.update(category=target)
|
||||
|
||||
deleted = False
|
||||
if delete_source:
|
||||
# safe to delete now (no FK references from Question)
|
||||
source.delete()
|
||||
deleted = True
|
||||
|
||||
msg = f"Moved {count} question{'s' if count != 1 else ''} from '{source}' to '{target}'."
|
||||
if deleted:
|
||||
msg += f" Deleted source category '{source}'."
|
||||
|
||||
return render(request, 'sbas/merge_category.html', {'categories': Category.objects.all().order_by('category'), 'success': msg})
|
||||
|
||||
|
||||
@login_required
|
||||
@user_passes_test(lambda u: u.is_superuser)
|
||||
@require_http_methods(["POST"])
|
||||
|
||||
Reference in New Issue
Block a user