from django.core.management.base import BaseCommand from django.db import transaction, models from apps.hadis.models import Hadis, HadisCorrection, TransmitterOriginalText class Command(BaseCommand): help = 'Refreshes slugs and share_links by re-saving all existing instances of models that store share_links in the database.' def add_arguments(self, parser): parser.add_argument( '--missing-only', action='store_true', help='Only update share_links that are empty or null', ) def handle(self, *args, **options): missing_only = options.get('missing_only') models_to_refresh = [ (Hadis, "Hadis"), (HadisCorrection, "Hadis Correction"), (TransmitterOriginalText, "Transmitter Original Text"), ] for model_class, name in models_to_refresh: self.stdout.write(self.style.WARNING(f'--- Processing {name} ---')) if missing_only: instances = model_class.objects.filter( models.Q(share_link__isnull=True) | models.Q(share_link='') ) else: instances = model_class.objects.all() count = instances.count() if count == 0: self.stdout.write(f"No {name} instances found to process.") continue processed = 0 # Using transaction.atomic to ensure database integrity with transaction.atomic(): for instance in instances: try: # Re-saving triggers the updated .save() logic which regenerates the share_link instance.save() processed += 1 if processed % 100 == 0: self.stdout.write(f"Updated {processed}/{count} {name}...") except Exception as e: self.stdout.write(self.style.ERROR( f"Error saving {name} ID {instance.id}: {str(e)}" )) self.stdout.write(self.style.SUCCESS(f'Successfully processed {processed} {name} instances.')) self.stdout.write(self.style.SUCCESS('--- All models processed successfully ---'))