from django.core.management.base import BaseCommand from django.db import transaction from django.utils.translation import gettext_lazy as _ from apps.chat.models import RoomMessage, ChatMessage, MessageReadStatus class Command(BaseCommand): help = 'Clear chat data: all rooms, messages and read statuses, but preserve course-related rooms' def add_arguments(self, parser): parser.add_argument( '--force', action='store_true', dest='force', help=_('Force deletion without confirmation'), ) parser.add_argument( '--all-rooms', action='store_true', dest='all_rooms', help=_('Delete ALL rooms including course-related rooms'), ) def handle(self, *args, **options): force = options['force'] all_rooms = options['all_rooms'] if not force: if all_rooms: confirm = input(_('This will delete ALL chat data including course rooms. Are you sure? (yes/no): ')) else: confirm = input(_('This will delete all messages and read statuses, and non-course rooms. Course rooms will be preserved but their messages will be deleted. Are you sure? (yes/no): ')) if confirm.lower() != 'yes': self.stdout.write(self.style.WARNING(_('Operation cancelled.'))) return try: with transaction.atomic(): # Count existing data total_messages = ChatMessage.objects.count() total_read_statuses = MessageReadStatus.objects.count() total_rooms = RoomMessage.objects.count() course_rooms = RoomMessage.objects.filter(course__isnull=False).count() non_course_rooms = RoomMessage.objects.filter(course__isnull=True).count() self.stdout.write(self.style.WARNING(f'Found:')) self.stdout.write(f' - {total_messages} messages') self.stdout.write(f' - {total_read_statuses} read statuses') self.stdout.write(f' - {total_rooms} total rooms ({course_rooms} course rooms, {non_course_rooms} non-course rooms)') # Step 1: Delete all MessageReadStatus records deleted_read_statuses = MessageReadStatus.objects.all().delete()[0] self.stdout.write(self.style.SUCCESS(f'✓ Deleted {deleted_read_statuses} MessageReadStatus records')) # Step 2: Delete all ChatMessage records deleted_messages = ChatMessage.objects.all().delete()[0] self.stdout.write(self.style.SUCCESS(f'✓ Deleted {deleted_messages} ChatMessage records')) # Step 3: Handle rooms based on options if all_rooms: # Delete ALL rooms deleted_rooms = RoomMessage.objects.all().delete()[0] self.stdout.write(self.style.SUCCESS(f'✓ Deleted {deleted_rooms} RoomMessage records (including course rooms)')) else: # Delete only non-course rooms (rooms without course relationship) deleted_non_course_rooms = RoomMessage.objects.filter(course__isnull=True).delete()[0] self.stdout.write(self.style.SUCCESS(f'✓ Deleted {deleted_non_course_rooms} non-course RoomMessage records')) # Reset unread_messages_count for course rooms course_rooms_updated = RoomMessage.objects.filter(course__isnull=False).update(unread_messages_count=0) self.stdout.write(self.style.SUCCESS(f'✓ Reset unread_messages_count for {course_rooms_updated} course rooms')) self.stdout.write(self.style.SUCCESS(_('Chat data clearing completed successfully!'))) except Exception as e: self.stdout.write(self.style.ERROR(f'Error occurred: {str(e)}')) raise