Files
MathApp/content/management/commands/purge_demo_data.py
Zareian 78130e7194 build the real curriculum from the textbook structure
تا پیش از این کلِ محتوای دیتابیس ردیف‌های [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>
2026-09-13 19:00:10 +03:30

88 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
پاک‌کردنِ ردیف‌های نمونه‌ی «[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'
))