تا پیش از این کلِ محتوای دیتابیس ردیفهای [DEMO] و [SEED] بود — دانشآموزِ
پایه نهم در دمو «جمع تا ۱۰» میدید. سینیور «یک بیسیکِ کامل با دیتای واقعی»
خواسته بود.
seed_curriculum_from_textbook (رایگان، هیچ فراخوانیِ پولی ندارد):
Grade ← پایهی کتاب
Unit ← فصلِ کتاب
Node ← درسِ داخلِ فصل، از فهرستِ خودِ کتاب
Lesson ← نوعِ مسئلهی استخراجشده در بازهی صفحهی همان درس
intro_text مستقیم از generalSolution کتاب میآید.
generate_questions_from_chunks سوالِ چهارگزینهای با گزینههای انحرافیِ
باورپذیر میسازد (هزینهدار، اعتبارسنجیِ سختگیرانه). سوال اینجا جدا شد
چون ساختنِ گزینهی انحرافیِ درست به مدل نیاز دارد.
purge_demo_data ردیفهای [SEED]/[DEMO] را گزارش و — فقط با --apply — پاک
میکند؛ بدونِ آن این ردیفها در دمو داخلِ API دیده میشوند.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
88 lines
4.2 KiB
Python
88 lines
4.2 KiB
Python
"""
|
||
پاککردنِ ردیفهای نمونهی «[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'
|
||
))
|