Files
test/app/model/clazz.py
T
2026-09-21 19:03:31 +08:00

69 lines
2.9 KiB
Python

"""班级表(需求 2.4)。"""
from __future__ import annotations
from datetime import date
from sqlalchemy import Date, ForeignKey, String, Text
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.model.assoc import class_teachers
from app.model.base import Base, SoftDeleteMixin, TimestampMixin
from app.model.constants import CLASS_STATUS_TEXT, ClassStatus
class Clazz(Base, TimestampMixin, SoftDeleteMixin):
__tablename__ = "clazz"
__table_args__ = {"comment": "班级表"}
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
class_no: Mapped[str] = mapped_column(String(30), unique=True, nullable=False, comment="班级编号,如 JAVA2401")
name: Mapped[str] = mapped_column(String(50), nullable=False, index=True, comment="班级名称")
direction: Mapped[str | None] = mapped_column(String(50), comment="班级方向,如 Java 就业班")
open_date: Mapped[date | None] = mapped_column(Date, comment="开课时间")
close_date: Mapped[date | None] = mapped_column(Date, comment="结课时间")
classroom: Mapped[str | None] = mapped_column(String(30), comment="教室")
capacity: Mapped[int | None] = mapped_column(default=40, comment="计划招生人数")
status: Mapped[int] = mapped_column(default=int(ClassStatus.RUNNING), nullable=False, comment="班级状态 1=在读 2=已结课 3=已解散")
head_teacher_id: Mapped[int | None] = mapped_column(ForeignKey("teacher.id"), comment="班主任(老师)")
advisor_id: Mapped[int | None] = mapped_column(ForeignKey("advisor.id"), comment="带班顾问")
description: Mapped[str | None] = mapped_column(Text, comment="班级说明")
# ---------------- 关系 ----------------
head_teacher: Mapped["Teacher"] = relationship(lazy="joined", foreign_keys=[head_teacher_id]) # noqa: F821
advisor: Mapped["Advisor"] = relationship(lazy="joined") # noqa: F821
teachers: Mapped[list["Teacher"]] = relationship( # noqa: F821
secondary=class_teachers,
back_populates="classes",
lazy="selectin",
)
# viewonly:人数统计走 DAO 的聚合查询,这个关系只在班级详情里用来展开学生
students: Mapped[list["Student"]] = relationship( # noqa: F821
back_populates="klass",
viewonly=True,
lazy="select",
)
# ---------------- 出参派生字段 ----------------
@property
def status_text(self) -> str:
return CLASS_STATUS_TEXT.get(self.status, "未知")
@property
def head_teacher_name(self) -> str | None:
return self.head_teacher.name if self.head_teacher else None
@property
def advisor_name(self) -> str | None:
return self.advisor.name if self.advisor else None
@property
def teacher_names(self) -> list[str]:
return [t.name for t in self.teachers if t.is_del == 0]
@property
def teacher_ids(self) -> list[int]:
return [t.id for t in self.teachers if t.is_del == 0]