Enhance migration process for rapids to shorts; skip normal rapids and provide user feedback on migration status

This commit is contained in:
Ross
2026-03-25 21:14:33 +00:00
parent 06fe73e2a3
commit d6487eae88
4 changed files with 33 additions and 5 deletions
+12
View File
@@ -72,11 +72,15 @@ class RapidAdmin(VersionAdmin):
from shorts.models import Question as ShortQuestion from shorts.models import Question as ShortQuestion
created = [] created = []
skipped = []
for rapid in queryset: for rapid in queryset:
# allow admin or any author to perform migration # allow admin or any author to perform migration
if request.user.is_superuser or rapid.author.filter(id=request.user.id).exists(): if request.user.is_superuser or rapid.author.filter(id=request.user.id).exists():
try: try:
q = ShortQuestion.from_rapid(rapid) q = ShortQuestion.from_rapid(rapid)
if q is None:
skipped.append(str(rapid.id))
else:
created.append(str(q.id)) created.append(str(q.id))
except Exception as e: except Exception as e:
self.message_user(request, f"Failed to migrate Rapid {rapid.id}: {e}", level=messages.ERROR) self.message_user(request, f"Failed to migrate Rapid {rapid.id}: {e}", level=messages.ERROR)
@@ -85,6 +89,8 @@ class RapidAdmin(VersionAdmin):
if created: if created:
self.message_user(request, f"Created shorts questions: {', '.join(created)}", level=messages.SUCCESS) self.message_user(request, f"Created shorts questions: {', '.join(created)}", level=messages.SUCCESS)
if skipped:
self.message_user(request, f"Skipped normal rapids (not migrated): {', '.join(skipped)}", level=messages.INFO)
migrate_to_shorts.short_description = "Migrate selected rapids to shorts" migrate_to_shorts.short_description = "Migrate selected rapids to shorts"
@@ -97,12 +103,16 @@ class ExamAdmin(VersionAdmin, admin.ModelAdmin):
from shorts.models import Question as ShortQuestion from shorts.models import Question as ShortQuestion
created = [] created = []
skipped = []
for exam in queryset: for exam in queryset:
for rapid in exam.exam_questions.all(): for rapid in exam.exam_questions.all():
# only allow if admin or author of rapid # only allow if admin or author of rapid
if request.user.is_superuser or rapid.author.filter(id=request.user.id).exists(): if request.user.is_superuser or rapid.author.filter(id=request.user.id).exists():
try: try:
q = ShortQuestion.from_rapid(rapid) q = ShortQuestion.from_rapid(rapid)
if q is None:
skipped.append(str(rapid.id))
else:
created.append(str(q.id)) created.append(str(q.id))
except Exception as e: except Exception as e:
self.message_user(request, f"Failed to migrate Rapid {rapid.id}: {e}", level=messages.ERROR) self.message_user(request, f"Failed to migrate Rapid {rapid.id}: {e}", level=messages.ERROR)
@@ -111,6 +121,8 @@ class ExamAdmin(VersionAdmin, admin.ModelAdmin):
if created: if created:
self.message_user(request, f"Created shorts questions: {', '.join(created)}", level=messages.SUCCESS) self.message_user(request, f"Created shorts questions: {', '.join(created)}", level=messages.SUCCESS)
if skipped:
self.message_user(request, f"Skipped normal rapids (not migrated): {', '.join(skipped)}", level=messages.INFO)
migrate_exam_questions.short_description = "Migrate all rapids in selected exam(s) to shorts" migrate_exam_questions.short_description = "Migrate all rapids in selected exam(s) to shorts"
+14 -2
View File
@@ -78,6 +78,7 @@ from django.core.cache import cache
from helpers.images import image_as_base64 from helpers.images import image_as_base64
import logging import logging
from django.contrib import messages
from copy import deepcopy from copy import deepcopy
from django.forms.models import model_to_dict from django.forms.models import model_to_dict
from rapids.forms import RapidCreationDefaultForm from rapids.forms import RapidCreationDefaultForm
@@ -834,8 +835,14 @@ def question_migrate_to_shorts(request, pk):
try: try:
q = ShortQuestion.from_rapid(rapid) q = ShortQuestion.from_rapid(rapid)
except Exception as e: except Exception as e:
return HttpResponse(f"Migration failed: {e}", status=500) messages.error(request, f"Migration failed: {e}")
return redirect("rapids:question_detail", pk=rapid.pk)
if q is None:
messages.info(request, "Question skipped (marked normal) — not migrated.")
return redirect("rapids:question_detail", pk=rapid.pk)
messages.success(request, "Migration complete — redirected to new Short question.")
return redirect(q.get_absolute_url()) return redirect(q.get_absolute_url())
@@ -855,11 +862,16 @@ def exam_migrate_rapids_to_shorts(request, pk):
for rapid in exam.exam_questions.all(): for rapid in exam.exam_questions.all():
try: try:
ShortQuestion.from_rapid(rapid) q = ShortQuestion.from_rapid(rapid)
if q is None:
# skipped normal
continue
except Exception: except Exception:
# continue on error # continue on error
continue continue
messages.success(request, "Exam migration attempted. Normal questions were skipped.")
# Redirect to the exam overview for shorts if available, otherwise back to rapids exam # Redirect to the exam overview for shorts if available, otherwise back to rapids exam
try: try:
return redirect("shorts:exam_overview", pk=exam.pk) return redirect("shorts:exam_overview", pk=exam.pk)
+4
View File
@@ -302,6 +302,10 @@ class Question(QuestionBase):
from rapids.models import Answer as RapidAnswer from rapids.models import Answer as RapidAnswer
# Skip migration for normal rapids (nothing to migrate)
if getattr(rapid, "normal", False):
return None
guidance_parts = [] guidance_parts = []
guidance_parts.append(f"Migrated from rapid id: {rapid.id}") guidance_parts.append(f"Migrated from rapid id: {rapid.id}")
if rapid.laterality: if rapid.laterality: