Subjects per grade (math, calculus, geometry, stats, discrete), 5 new textbooks, 202 new islands, long islands split, hand-written figures and lesson texts for the new books
- content.Subject + Unit.subject, /api/home?subject=, tutor grounded in the chosen book - 5 new books ingested; ~1150 hand-written questions, islands named by hand - node_split: islands over 7 lessons split into parts of <=6 (lesson ids and progress kept) - Lesson.figures hand-authored and visually checked for 653 lessons of the new books; gen_lesson_figures got --subject and survives network errors - seed files re-exported Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -102,6 +102,8 @@ def parse(raw: bytes) -> list[dict]:
|
||||
})
|
||||
|
||||
clean_units.append({
|
||||
# کتاب صریح است: فایلِ بیکتاب رد میشود تا فصلِ حسابان بیصدا «ریاضی» نشود.
|
||||
'subject': _text(unit.get('subject'), 'subject', uwhere),
|
||||
'title': _text(unit.get('title'), 'title', uwhere),
|
||||
'blurb': str(unit.get('blurb') or '')[:120],
|
||||
'order': int(unit.get('order') or ui + 1),
|
||||
@@ -117,6 +119,16 @@ def parse(raw: bytes) -> list[dict]:
|
||||
return cleaned
|
||||
|
||||
|
||||
def _subject_or_error(title: str):
|
||||
"""کتابِ فایل باید از قبل در جدولِ Subject باشد (ادمین ← کتابها)؛ نامِ ناشناخته خطا است، نه ساختنِ بیصدا."""
|
||||
from .models import Subject
|
||||
subject = Subject.objects.filter(title=title).first()
|
||||
if subject is None:
|
||||
known = '، '.join(Subject.objects.values_list('title', flat=True))
|
||||
raise CurriculumError(f'کتابِ «{title}» در جدولِ کتابها نیست. موجود: {known}')
|
||||
return subject
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def import_curriculum(grades: list[dict]) -> dict:
|
||||
"""
|
||||
@@ -135,9 +147,10 @@ def import_curriculum(grades: list[dict]) -> dict:
|
||||
counts['grades'] += 1 if created else 0
|
||||
|
||||
for unit_row in grade_row['units']:
|
||||
subject = _subject_or_error(unit_row['subject'])
|
||||
unit, created = Unit.objects.get_or_create(
|
||||
grade=grade, title=unit_row['title'],
|
||||
defaults={'order': unit_row['order']},
|
||||
defaults={'order': unit_row['order'], 'subject': subject},
|
||||
)
|
||||
counts['units'] += 1 if created else 0
|
||||
# متنِ ادمین برنده است: فقط خانهی خالی از فایل پر میشود
|
||||
@@ -185,13 +198,14 @@ def import_curriculum(grades: list[dict]) -> dict:
|
||||
def export_curriculum(grades_queryset) -> dict:
|
||||
"""خروجی دقیقاً همان قالبیست که import میخواند."""
|
||||
out = []
|
||||
for grade in grades_queryset.prefetch_related('units__nodes__lessons'):
|
||||
for grade in grades_queryset.prefetch_related('units__subject', 'units__nodes__lessons'):
|
||||
out.append({
|
||||
'title': grade.title,
|
||||
'icon': grade.icon,
|
||||
'color': grade.color,
|
||||
'units': [
|
||||
{
|
||||
'subject': unit.subject.title,
|
||||
'title': unit.title,
|
||||
'order': unit.order,
|
||||
**({'blurb': unit.blurb} if unit.blurb else {}),
|
||||
|
||||
Reference in New Issue
Block a user