初始化前后端学生管理系统项目
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
# 请求体
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
|
||||
class ScoreCreate(BaseModel):
|
||||
stu_id: int=Field(...,ge=1,description='学生id必须大于等于1')
|
||||
exam_id: int=Field(...,ge=1,description='考核序次必须大于等于1')
|
||||
score: int=Field(...,ge=0,le=100,description='成绩必须在0-100之间')
|
||||
|
||||
|
||||
class ScoreUpdate(BaseModel):
|
||||
# stu_id: int = Field(None, ge=1, description='学生id必须大于等于1')
|
||||
# exam_id: int = Field(None, ge=1, description='考核序次必须大于等于1')
|
||||
score: int = Field(None, ge=0, le=100, description='成绩必须在0-100之间')
|
||||
@@ -0,0 +1,12 @@
|
||||
from datetime import datetime
|
||||
from pydantic import BaseModel,Field
|
||||
#引入Pydantic数据校验。
|
||||
class AdvisorIn(BaseModel):
|
||||
advisor_id: int=Field(...,ge=1,description="顾问ID")
|
||||
advisor_name: str=Field(...,min_length=2,max_length=8,description="姓名为2~8个字符")
|
||||
|
||||
class AdvisorOut(BaseModel):
|
||||
advisor_id: int
|
||||
advisor_name: str
|
||||
class Config:
|
||||
from_attributes = True
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
|
||||
|
||||
from pydantic import BaseModel, Field, ConfigDict # BaseModel=模型基类,Field=字段规则,ConfigDict=模型配置
|
||||
from datetime import date # Python的日期类型(只有年月日)
|
||||
from typing import Optional # Optional[X] 表示"可以是X,也可以是None"
|
||||
|
||||
# ---------------- 请求模型 ----------------
|
||||
# 新增班级:class_id、start_time 必填
|
||||
# 请求模型 = 前端传过来的数据长什么样,FastAPI自动帮你校验
|
||||
class ClassCreate(BaseModel):# 新增班级的入参模型:POST新增时,请求体必须符合这个结构
|
||||
class_id: int = Field(..., ge=1, description="班级编号,正整数,不能重复")
|
||||
start_time: date = Field(..., description="开班日期,格式 yyyy-MM-dd")
|
||||
# description:这行字会显示在Swagger文档里,方便前端看
|
||||
|
||||
# 修改班级:字段可选,前端传哪个改哪个(局部更新)
|
||||
class ClassUpdate(BaseModel):
|
||||
# class_id: int = Field( ge=1, description="班级编号,可选") 被注释掉 = 不允许修改班级编号
|
||||
start_time: Optional[date] = Field(None, description="开班日期,格式 yyyy-MM-dd")
|
||||
# Optional[date] = 可以传日期也可以不传;Field(None) = 不传时默认值是None
|
||||
|
||||
|
||||
# ---------------- 响应模型 ----------------
|
||||
# 响应模型:后端返回给前端的数据结构,from_attributes 允许直接从 ORM (Classinfo实例)的属性取值,不用手动一个个赋值
|
||||
class ClassResponse(BaseModel):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
class_id: int # 返回字段:班级编号
|
||||
start_time: date# 返回字段:开班日期
|
||||
|
||||
|
||||
|
||||
|
||||
#逻辑:**三个模型管三种场景**—— 新增(必填)、修改(可选)、响应(输出)。
|
||||
# 前端传错类型 / 缺字段,FastAPI 直接返回 422,不会把脏数据送进数据库。
|
||||
@@ -0,0 +1,65 @@
|
||||
# 就业开放时间和offer下发时间校验
|
||||
# 导入基类、过滤条件、校验器
|
||||
from pydantic import BaseModel, Field, model_validator, field_validator
|
||||
# 导入时间模块
|
||||
from datetime import date, datetime
|
||||
# 导入可选类型、列表类型
|
||||
from typing import Optional, List
|
||||
|
||||
# ---------- 请求模型 ----------
|
||||
|
||||
# 修改就业记录
|
||||
class EmploymentOfferUpdate(BaseModel):
|
||||
offer_time: Optional[date] = None
|
||||
|
||||
|
||||
# 修改就业基础
|
||||
class EmploymentBaseUpdate(BaseModel):
|
||||
employment_open_time: Optional[date] = None
|
||||
job_time: Optional[date] = None
|
||||
company_name: Optional[str] = None
|
||||
salary: Optional[float] = None
|
||||
|
||||
# 添加就业基础
|
||||
class EmploymentBaseCreate(BaseModel):
|
||||
stu_id: int = Field(..., description="学生编号")
|
||||
job_time: Optional[date] = Field(None, description="实际去就职时间")
|
||||
employment_open_time: date = Field(description="就业开放时间:年-月-日")
|
||||
company_name: str = Field(max_length=100, description="就业公司")
|
||||
salary: float = Field(..., gt=0, description="就业薪资,保留2位小数")
|
||||
|
||||
# 添加就业记录
|
||||
class EmploymentOfferCreate(BaseModel):
|
||||
stu_id: int = Field(..., description="学生编号")
|
||||
offer_id: int = Field(..., description="offer编号")
|
||||
offer_time: date = Field(description="offer下发时间:年-月-日")
|
||||
|
||||
# 多条件组合查询
|
||||
class EmploymentQuery(BaseModel):
|
||||
stu_id: Optional[int] = None
|
||||
company_name: Optional[str] = Field(None, max_length=100, description="公司名称")
|
||||
min_salary: Optional[float] = None
|
||||
max_salary: Optional[float] = None
|
||||
|
||||
|
||||
# ---------- 响应模型 ----------
|
||||
# 就业记录查询响应
|
||||
class EmploymentOfferQueryResponse(BaseModel):
|
||||
stu_id: int
|
||||
offer_id: int
|
||||
offer_time: date
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# 就业基础查询响应
|
||||
class EmploymentBaseQueryResponse(BaseModel):
|
||||
stu_id: int
|
||||
employment_open_time: Optional[date] = None
|
||||
job_time: Optional[date] = None
|
||||
company_name: Optional[str] = None
|
||||
salary: Optional[float] = None
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
@@ -0,0 +1,36 @@
|
||||
from pydantic import BaseModel, Field, model_validator
|
||||
|
||||
class StudentAge(BaseModel):
|
||||
age_star: int | None = Field(None, gt=0)
|
||||
age_end: int | None = Field(None, gt=0)
|
||||
age_value: int | None = Field(None, gt=0)
|
||||
|
||||
@model_validator(mode="after")
|
||||
def check_age(self):
|
||||
if self.age_value is not None:
|
||||
if self.age_star is not None or self.age_end is not None:
|
||||
raise ValueError('age_value和age_star/age_end区间不能同时存在')
|
||||
else:
|
||||
if self.age_star is None or self.age_end is None:
|
||||
raise ValueError('区间需填写完整')
|
||||
if self.age_star is not None and self.age_end is not None:
|
||||
if self.age_star > self.age_end:
|
||||
raise ValueError('输入起始值不能大于终止值')
|
||||
return self
|
||||
|
||||
class ClassCount(BaseModel):
|
||||
class_id: int = Field(..., gt=0)
|
||||
gender: str | None = Field(None, description="可填男/女")
|
||||
|
||||
class ScoreCount(BaseModel):
|
||||
score: int = Field(..., ge=0, le=100)
|
||||
num: int | None = Field(None, gt=0)
|
||||
|
||||
class ScoreAvg(BaseModel):
|
||||
exam_order: int = Field(...)
|
||||
|
||||
class Employment(BaseModel):
|
||||
top: int = Field(...)
|
||||
|
||||
class EmploymentOff(BaseModel):
|
||||
class_id: int = Field(...)
|
||||
@@ -0,0 +1,67 @@
|
||||
# scheme/student.py
|
||||
from pydantic import BaseModel, Field,model_validator
|
||||
from datetime import datetime, date
|
||||
from typing import Optional
|
||||
|
||||
# ---------- 请求体模型 ----------
|
||||
class StudentCreate(BaseModel):
|
||||
stu_id: int = Field(..., ge = 1)
|
||||
class_id: int = Field(..., ge = 1)
|
||||
advisor_id: int = Field(..., ge=1, description="顾问老师id,对应 advisors.advisor_id")
|
||||
stu_name: str = Field(..., min_length=1, max_length=10)
|
||||
native_place: str = Field(..., min_length=1, max_length=30)
|
||||
graduate_school: str = Field(..., min_length=1, max_length=50)
|
||||
education: str = Field(..., min_length=1, max_length=10)
|
||||
major: str = Field(..., min_length=1, max_length=20)
|
||||
age: int = Field(..., ge = 18, le =40)
|
||||
gender: str = Field(..., min_length=1, max_length=20)
|
||||
graduate_time:date= Field(...)
|
||||
enroll_time:date= Field(...)
|
||||
|
||||
|
||||
# 模型校验,时间判断
|
||||
# @model_validator (mode = "after")
|
||||
# def check_time(self):
|
||||
# # 入学时间不能晚于就业时间
|
||||
# if self.graduate_time is not None:
|
||||
# if self.graduate_time < self.enroll_time:
|
||||
# raise ValueError ("毕业时间不能早于入学时间!!!")
|
||||
# # 简历开放时间不能早于入学时间
|
||||
# # if self.employment_open_time < self.enroll_time:
|
||||
# # raise ValueError("简历开放时间不能早于入学时间")
|
||||
# # 简历开放时间不能晚于毕业时间
|
||||
# if self.graduate_time is not None:
|
||||
# if self.graduate_time < self.employment_open_time:
|
||||
# raise ValueError("简历开放时间不能晚于毕业时间!!!")
|
||||
# # mode="after" 的校验器必须返回 self,否则 Pydantic v2 会把整个模型变成 None
|
||||
# return self
|
||||
|
||||
|
||||
class StudentUpdate(BaseModel):
|
||||
class_id: Optional[int] = Field(None)
|
||||
advisor_id: Optional[int] = Field(None, ge=1)
|
||||
stu_name: Optional[str] = Field(None, min_length=1, max_length=10)
|
||||
native_place: Optional[str] = Field(None, min_length=1, max_length=30)
|
||||
graduate_school: Optional[str] = Field(None, min_length=1, max_length=50)
|
||||
education: Optional[str] = Field(None, min_length=1, max_length=10)
|
||||
major: Optional[str] = Field(None, min_length=1, max_length=20)
|
||||
age: Optional[int] = Field(None, ge = 18, le =40)
|
||||
gender: Optional[str] = Field(None, min_length=1, max_length=20)
|
||||
|
||||
# ----------响应体模型-------------
|
||||
class StudentResponse(BaseModel):
|
||||
stu_id: int
|
||||
class_id: int # 数据库非空,这里必须是 int
|
||||
stu_name: str
|
||||
native_place: str
|
||||
graduate_school: Optional[str]
|
||||
education: str
|
||||
major: Optional[str]
|
||||
# 敏感字段已在此模型中脱敏
|
||||
|
||||
class Config:
|
||||
from_attributes = True #支持orm对象转换,让pydantic可以读取ORM数据库对象(SQLAlchemy模型)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
# 正确
|
||||
from pydantic import Field
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, field_validator
|
||||
|
||||
|
||||
# --------------------请求体模型-----------------------------
|
||||
# 用于增加1行数据# 加了软删除标签
|
||||
class TeacherAdd(BaseModel):
|
||||
teacher_id:int=Field(...,ge=1,description='教师ID是整数类型')
|
||||
class_id:int=Field(...,ge=1,description='班级ID是整数类型')
|
||||
teacher_name:str=Field(...,description='教师姓名')
|
||||
job_name:str=Field(...,min_length=2,description='主讲老师、班主任、助教')
|
||||
is_deleted:int=Field(0,ge=0,le=0,description='只能输入0,0代表未删除,1代表已经被软删除')
|
||||
|
||||
@field_validator("job_name")
|
||||
@classmethod
|
||||
def validate_job_name(cls, v):
|
||||
"""校验 job_name 必须是 主讲/班主任/助教 之一"""
|
||||
allowed = ["主讲老师", "班主任", "助教"]
|
||||
if v not in allowed:
|
||||
raise ValueError(f"job_name 必须是 {allowed} 之一,当前值: {v}")
|
||||
return v
|
||||
# 用于更新数据
|
||||
class TeacherUpdate(BaseModel):
|
||||
class_id: Optional[int] = Field(None, ge=1, description='班级ID是整数类型') # ge=1 只对非 None 的值生效
|
||||
teacher_name: Optional[str] = Field(None, description='教师姓名')
|
||||
job_name: Optional[str] = Field(None,min_length=2, description='主讲老师、班主任、助教')
|
||||
|
||||
@field_validator("job_name")
|
||||
@classmethod
|
||||
def validate_job_name(cls, v):
|
||||
"""校验 job_name 必须是 主讲/班主任/助教 之一"""
|
||||
allowed = ["主讲老师", "班主任", "助教"]
|
||||
if v not in allowed:
|
||||
raise ValueError(f"job_name 必须是 {allowed} 之一,当前值: {v}")
|
||||
return v
|
||||
# --------------------- 响应模型 ----------------------------
|
||||
class TeacherResponse(BaseModel):
|
||||
teacher_id: int
|
||||
class_id: int
|
||||
teacher_name: str
|
||||
job_name: str
|
||||
|
||||
class Config: # 告诉 Pydantic:"可以从任意对象的属性中读取数据,而不只是从字典中读取。"
|
||||
from_attributes = True # 支持 ORM 对象转换
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user