from django.core.management.base import BaseCommand from django.db.models import Q from apps.quiz.models import Quiz from apps.course.models import CourseLesson class Command(BaseCommand): help = "Sync lesson_number for all quizzes connected to a lesson." def add_arguments(self, parser): parser.add_argument( '--dry-run', action='store_true', help='Preview updates without saving changes.', ) def handle(self, *args, **options): dry_run = options['dry_run'] updated_quizzes = 0 # We filter quizzes that have a lesson assigned quizzes = Quiz.objects.filter(lesson__isnull=False) for quiz in quizzes: lesson = quiz.lesson course = quiz.course or lesson.course if not course: self.stdout.write( self.style.WARNING(f"Quiz {quiz.id} has lesson {lesson.id} but no associated course found.") ) continue # Find all active lessons for this course to calculate position lessons_list = list(CourseLesson.objects.filter( course=course, is_active=True ).filter( Q(chapter__isnull=True) | Q(chapter__is_active=True) ).order_by('chapter__priority', 'priority')) try: pos = lessons_list.index(lesson) + 1 except ValueError: # Lesson might not be active, or not in the course's active list self.stdout.write( self.style.WARNING( f"Quiz {quiz.id}: Lesson {lesson.id} is not active or not in course active list. Skipping." ) ) continue needs_update = False update_fields = [] if quiz.lesson_number != pos: self.stdout.write( f"Quiz {quiz.id}: lesson_number {quiz.lesson_number} -> {pos}" ) quiz.lesson_number = pos needs_update = True update_fields.append('lesson_number') if not quiz.course: self.stdout.write(f"Quiz {quiz.id}: setting course to {course.id}") quiz.course = course needs_update = True update_fields.append('course') if needs_update: updated_quizzes += 1 if not dry_run: quiz.save(update_fields=update_fields) if dry_run: self.stdout.write( self.style.WARNING( f"Dry run complete. {updated_quizzes} quiz(zes) would be updated." ) ) else: self.stdout.write( self.style.SUCCESS( f"Sync complete. {updated_quizzes} quiz(zes) updated." ) )