from django.core.management.base import BaseCommand from django.db import transaction from django.db.models import F from apps.hadis.models import Hadis, HadisTransmitter, NarratorLayer class Command(BaseCommand): help = "Fast chunked fix for HadisTransmitter narrator_layer foreign keys." def handle(self, *args, **options): self.stdout.write("Finding unique Hadiths with mismatched transmitter layers...") mismatched_hadis_ids = list(set( HadisTransmitter.objects.filter(narrator_layer__isnull=False) .exclude(narrator_layer__hadis=F('hadis')) .values_list('hadis_id', flat=True) )) total = len(mismatched_hadis_ids) self.stdout.write(f"Found {total} Hadiths to fix. Processing in chunks of 50...") chunk_size = 50 for i in range(0, total, chunk_size): chunk = mismatched_hadis_ids[i:i + chunk_size] with transaction.atomic(): for hadis_id in chunk: hadis = Hadis.objects.get(id=hadis_id) layers = list(hadis.narrator_layers.all().order_by('number')) if not layers: l1 = NarratorLayer.objects.create( hadis=hadis, number=1, name=[{"language_code": "en", "text": "Primary Transmitters"}], description=[{"language_code": "en", "text": "Primary transmitters layer"}] ) l2 = NarratorLayer.objects.create( hadis=hadis, number=2, name=[{"language_code": "en", "text": "Secondary Transmitters"}], description=[{"language_code": "en", "text": "Secondary transmitters layer"}] ) layers = [l1, l2] if len(layers) == 1: HadisTransmitter.objects.filter(hadis_id=hadis_id).update(narrator_layer=layers[0]) else: HadisTransmitter.objects.filter(hadis_id=hadis_id, order__lte=1).update(narrator_layer=layers[0]) HadisTransmitter.objects.filter(hadis_id=hadis_id, order__gt=1).update(narrator_layer=layers[1]) self.stdout.write(f"Fixed {min(i + chunk_size, total)}/{total} Hadiths...") self.stdout.write(self.style.SUCCESS("Done! All Hadiths transmitter layers successfully fixed!"))