# scheme/students.py # 学生模块的请求/响应模型 from datetime import date from typing import List, Optional from pydantic import BaseModel, Field, field_validator # -------------------- 请求体模型 ----------------------------- class StudentAdd(BaseModel): """创建学生:stu_id 不传则按规则自动生成(入学年份+班级号+序号)""" stu_id: Optional[int] = Field(None, ge=1, description="学号(不传则自动生成)") class_id: int = Field(..., ge=1, description="学生班级ID") stu_name: str = Field(..., min_length=1, max_length=10, description="学生姓名") native_place: str = Field(..., min_length=1, description="籍贯") graduate_school: str = Field(..., min_length=1, description="毕业院校") major: str = Field(..., min_length=1, description="专业") enroll_time: date = Field(..., description="入学时间 YYYY-MM-DD") graduate_time: date = Field(..., description="毕业时间 YYYY-MM-DD") education: str = Field(..., description="学历:大专/本科/硕士等") age: int = Field(..., ge=15, le=60, description="年龄") gender: str = Field(..., description="性别:男/女") advisor_id: int = Field(..., ge=1, description="顾问编号") status: str = Field("在读", description="状态:在读/进入就业/已就业") @field_validator("gender") @classmethod def validate_gender(cls, v): if v not in ("男", "女"): raise ValueError(f"gender 必须是 男/女,当前值: {v}") return v @field_validator("status") @classmethod def validate_status(cls, v): allowed = ["在读", "进入就业", "已就业"] if v not in allowed: raise ValueError(f"status 必须是 {allowed} 之一,当前值: {v}") return v class StudentUpdate(BaseModel): """更新学生:只更新显式传入的非 None 字段;class_id/advisor_id 不允许改(保持归属一致性)""" stu_name: Optional[str] = Field(None, min_length=1, max_length=10, description="学生姓名") native_place: Optional[str] = Field(None, min_length=1, description="籍贯") graduate_school: Optional[str] = Field(None, min_length=1, description="毕业院校") major: Optional[str] = Field(None, min_length=1, description="专业") enroll_time: Optional[date] = Field(None, description="入学时间") graduate_time: Optional[date] = Field(None, description="毕业时间") education: Optional[str] = Field(None, description="学历") age: Optional[int] = Field(None, ge=15, le=60, description="年龄") gender: Optional[str] = Field(None, description="性别:男/女") status: Optional[str] = Field(None, description="状态:在读/进入就业/已就业") @field_validator("gender") @classmethod def validate_gender(cls, v): if v is not None and v not in ("男", "女"): raise ValueError(f"gender 必须是 男/女,当前值: {v}") return v @field_validator("status") @classmethod def validate_status(cls, v): allowed = ["在读", "进入就业", "已就业"] if v is not None and v not in allowed: raise ValueError(f"status 必须是 {allowed} 之一,当前值: {v}") return v # -------------------- 响应模型 ---------------------------- class StudentResponse(BaseModel): stu_id: int stu_name: str native_place: str graduate_school: str major: str enroll_time: date graduate_time: date education: str age: int gender: str class_id: int advisor_id: int status: str class_name: Optional[str] = Field(None, description="冗余展示:班级名称") advisor_name: Optional[str] = Field(None, description="冗余展示:顾问姓名") class Config: from_attributes = True class StudentListResponse(BaseModel): total: int items: List[StudentResponse]