from django.core.management.base import BaseCommand from django.utils import timezone from rog.models import GpsLog class Command(BaseCommand): help = '失敗した外部システム登録をリトライします' def add_arguments(self, parser): parser.add_argument( '--max-attempts', type=int, default=3, help='最大試行回数 (デフォルト: 3)' ) parser.add_argument( '--dry-run', action='store_true', help='実際の処理を実行せず、処理予定の記録のみを表示' ) def handle(self, *args, **options): max_attempts = options['max_attempts'] dry_run = options['dry_run'] self.stdout.write( self.style.SUCCESS(f'外部システム登録リトライ処理を開始します (最大試行回数: {max_attempts})') ) # 保留中の外部システム登録を取得 pending_records = GpsLog.get_pending_external_registrations().filter( external_registration_attempts__lt=max_attempts ) if not pending_records.exists(): self.stdout.write( self.style.WARNING('リトライが必要な記録が見つかりませんでした。') ) return self.stdout.write(f'リトライ対象の記録数: {pending_records.count()}') if dry_run: self.stdout.write(self.style.WARNING('-- DRY RUN モード --')) for record in pending_records: self.stdout.write( f' ゼッケン番号: {record.zekken_number}, ' f'イベント: {record.event_code}, ' f'チーム名: {record.team_name}, ' f'試行回数: {record.external_registration_attempts}' ) return # 実際のリトライ処理 result = GpsLog.retry_failed_external_registrations(max_attempts) self.stdout.write( self.style.SUCCESS( f'リトライ完了: 成功 {result["success_count"]}件, ' f'失敗 {result["failed_count"]}件, ' f'合計処理数 {result["total_processed"]}件' ) ) # 最大試行回数に達した記録があるかチェック max_attempts_reached = GpsLog.get_pending_external_registrations().filter( external_registration_attempts__gte=max_attempts ) if max_attempts_reached.exists(): self.stdout.write( self.style.ERROR( f'警告: {max_attempts_reached.count()}件の記録が最大試行回数に達しました。' ' 手動での確認が必要です。' ) ) # 詳細を表示 for record in max_attempts_reached[:5]: # 最初の5件のみ表示 self.stdout.write( f' ゼッケン番号: {record.zekken_number}, ' f'イベント: {record.event_code}, ' f'エラー: {record.external_registration_error}' )