# `courses` Courses & Seasonal Schedules Author: Zhenyu Yang , Sixu Wei Last updated: Apr 24, 2026 Corresponding API docs: [Course API](../../api/courses.md) ## `courses` Code Entry - `backend/apps/courses/models/__init__.py` - `backend/apps/courses/views.py` - `backend/apps/courses/services/__init__.py` ## `courses` Core Data ### `Course` The course master record, storing basic course information, teacher, class, course number, semester range, and raw import fields. ### `CourseOccurrence` A single class session instance, storing: - `occurrence_date` - `classroom` - `sections` - `schedule_key` - `status` - `source_type` - `remark` At runtime, `CourseOccurrence` serves as the source of truth for scheduled classes; the system no longer derives actual classes from an independent periodic schedule table. ## Query Model - `CourseViewSet` is a read-only ViewSet. - Supported filters: - `teacher_id` - `class_name` - `start_date` - `end_date` - Queries prefetch occurrences with `status in (scheduled, rescheduled)`. - When a date range is provided: - The course set only includes courses that have occurrences within the range. - `sessions` are also trimmed accordingly. ## Import, Export & Template ### Import Template - Entry: `GET /courses/import-template` - `superadmin` / `secretary` only. - The template is dynamically generated by the backend. ### Excel Import - Entry: `POST /courses/import` - `superadmin` / `secretary` only. - File format: `.xlsx` / `.xls`, max 50MB. - Business rules are governed by `CourseImportService`; the current implementation retains the following key constraints: - Import must include `semester_start_date`. - Records where the administrative class column (`行政班`) contains `UC` are imported directly. - Other records are only imported for the 2nd and 3rd floors of Building 5. - Physical education courses have a special branch. - When the number of successfully processed records is greater than 0, `semester_start_date` is written back to `SystemConfig`. ### Export - Entry: `GET /courses/export` - `superadmin` / `secretary` only. - Export data re-aggregates occurrences by pattern for generating an Excel weekly view. ## Rescheduling - Entry: `POST /courses/sessions/{session_id}/reschedule` - Permissions: - The current course teacher - `superadmin` - `secretary` - `assistant` - The current implementation requires the new time range to fully match a standard class period; cross-day rescheduling is not supported. - The rescheduling date must fall within the course's `start_date` to `end_date`. ## Seasonal Schedules - Class period times are not hardcoded in models; they are dynamically resolved by `SeasonConfigService`. - At runtime, the system switches between winter and summer schedules based on `SystemConfig.season`. - Changing the season setting clears the course time cache. ## `courses` and Other Modules - `classrooms.schedule` and `signage.schedule` both depend on expanded course instance results. - `borrowings` course conflict detection depends on course instances. - `checkins` uses `CourseOccurrence` to create check-in sessions.