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( '--event-code', type=str, help='特定のイベントコードでフィルタ' ) parser.add_argument( '--status', type=str, choices=['pending', 'success', 'failed', 'retry'], help='特定のステータスでフィルタ' ) parser.add_argument( '--show-details', action='store_true', help='詳細情報を表示' ) def handle(self, *args, **options): event_code = options.get('event_code') status = options.get('status') show_details = options['show_details'] self.stdout.write( self.style.SUCCESS('外部システム登録状況を確認しています...') ) # フィルタ条件を構築 queryset = GpsLog.objects.filter( serial_number=-1, cp_number="EXTERNAL_REG" ) if event_code: queryset = queryset.filter(event_code=event_code) if status: queryset = queryset.filter(external_registration_status=status) # 統計情報 total_count = queryset.count() pending_count = queryset.filter(external_registration_status='pending').count() success_count = queryset.filter(external_registration_status='success').count() failed_count = queryset.filter(external_registration_status='failed').count() retry_count = queryset.filter(external_registration_status='retry').count() self.stdout.write(f'\n=== 外部システム登録統計 ===') self.stdout.write(f'合計記録数: {total_count}') self.stdout.write(f'保留中: {pending_count}') self.stdout.write(f'成功: {success_count}') self.stdout.write(f'失敗: {failed_count}') self.stdout.write(f'リトライ要求: {retry_count}') if show_details and queryset.exists(): self.stdout.write(f'\n=== 詳細情報 ===') for record in queryset.order_by('-create_at')[:20]: # 最新20件 status_color = self.get_status_color(record.external_registration_status) self.stdout.write( f'[{record.create_at.strftime("%Y-%m-%d %H:%M")}] ' f'ゼッケン: {record.zekken_number} | ' f'イベント: {record.event_code} | ' f'チーム: {record.team_name} | ' f'ステータス: {status_color(record.external_registration_status)} | ' f'試行回数: {record.external_registration_attempts}' ) if record.external_registration_error: self.stdout.write(f' エラー: {record.external_registration_error[:100]}...') # リトライが必要な記録をハイライト needs_retry = queryset.filter( external_registration_status__in=['pending', 'retry'], external_registration_attempts__lt=3 ) if needs_retry.exists(): self.stdout.write( self.style.WARNING( f'\n注意: {needs_retry.count()}件の記録がリトライを待機中です。' ' `python manage.py retry_external_registrations` でリトライできます。' ) ) # 最大試行回数に達した記録をチェック max_attempts_reached = queryset.filter( external_registration_attempts__gte=3, external_registration_status__in=['pending', 'failed', 'retry'] ) if max_attempts_reached.exists(): self.stdout.write( self.style.ERROR( f'\n警告: {max_attempts_reached.count()}件の記録が最大試行回数に達しています。' ' 手動での確認が必要です。' ) ) def get_status_color(self, status): """ステータスに応じた色付き表示を返す""" if status == 'success': return self.style.SUCCESS elif status == 'failed': return self.style.ERROR elif status in ['pending', 'retry']: return self.style.WARNING else: return lambda x: x