""" پاک‌کردنِ ردیف‌های نمونه‌ی «[SEED]» و «[DEMO]» از دیتابیسِ محلی. چرا لازم است: این ردیف‌ها در APIهای واقعی دیده می‌شوند — «[DEMO] پایهٔ نمونه» در `/api/grades`، «[SEED] ماهانه» در پلن‌ها، «[SEED] کاربر اصلی» در لیدربورد — و در دمو کنارِ محتوای واقعیِ کتاب بد به نظر می‌رسند. برگشت‌پذیر است: `python manage.py seed_test_data` دوباره می‌سازدشان. python manage.py purge_demo_data # فقط نشان می‌دهد python manage.py purge_demo_data --apply # واقعاً پاک می‌کند """ from django.core.management.base import BaseCommand from django.db import transaction PREFIXES = ('[SEED]', '[DEMO]') class Command(BaseCommand): help = 'پاک‌کردنِ ردیف‌های نمونه‌ی [SEED]/[DEMO] (برگشت‌پذیر با seed_test_data).' def add_arguments(self, parser): parser.add_argument('--apply', action='store_true', help='بدونِ این فقط گزارش می‌دهد و چیزی پاک نمی‌کند.') def handle(self, *args, **opts): from accounts.models import User from content.models import Grade from progress.models import Character from subscription.models import Plan # (مدل، نامِ فیلدِ متنی) — همه‌ی جاهایی که seed_test_data برچسب می‌زند. targets = [ (Grade, 'title'), (Plan, 'title'), (Character, 'name'), (User, 'name'), ] found = [] for model, field in targets: queryset = model.objects.none() for prefix in PREFIXES: queryset = queryset | model.objects.filter(**{f'{field}__startswith': prefix}) rows = list(queryset.distinct()) if rows: found.append((model, field, rows)) if not found: self.stdout.write(self.style.SUCCESS('هیچ ردیفِ نمونه‌ای پیدا نشد.')) return self.stdout.write(self.style.MIGRATE_HEADING('\nردیف‌های نمونه\n')) total = 0 for model, field, rows in found: self.stdout.write(f' {model.__name__} — {len(rows)} ردیف') for row in rows[:8]: self.stdout.write(f' #{row.pk} {getattr(row, field)}') if len(rows) > 8: self.stdout.write(f' … و {len(rows) - 8} مورد دیگر') total += len(rows) # هشدارِ لازم: بعضی از این‌ها تنها دادهٔ آن endpoint هستند. empties = [ name for model, name in ((Plan, 'subscription/plans'), (Character, 'characters')) if model.objects.count() == len([r for m, _f, rows in found if m is model for r in rows]) ] if empties: self.stdout.write(self.style.WARNING( '\n⚠ بعد از پاک‌کردن این endpointها خالی می‌شوند: ' + '، '.join(empties) + '\n (پلن و کاراکتر را ادمین در جنگو-ادمین می‌سازد؛ اگر برای دمو ' 'لازم‌اند، اول واقعی‌شان را بساز بعد این را اجرا کن.)' )) if not opts['apply']: self.stdout.write(self.style.WARNING( f'\n{total} ردیف. چیزی پاک نشد — برای پاک‌کردن --apply بدهید.' )) return # حذفِ آبشاری: Grade کلِ زیردرختِ Unit/Node/Lesson/Question را می‌برد، # و User سشن‌ها و پاسخ‌هایش را. همه‌شان دادهٔ نمونه‌اند. with transaction.atomic(): for model, _field, rows in found: model.objects.filter(pk__in=[r.pk for r in rows]).delete() self.stdout.write(self.style.SUCCESS(f'\n{total} ردیفِ نمونه پاک شد.')) self.stdout.write(self.style.HTTP_INFO( 'برای برگرداندن: python manage.py seed_test_data' ))