# api/users.py # 本文件定义学生相关的所有 API 路由(Controller 层) from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from typing import List, Optional # 注意下面这三行,坚决把开头 的 sqlalchemy_fastapi_demo. 删掉! from database import get_db from dao.students_dao import StudentDAO from scheme.students import StudentCreate, StudentUpdate, StudentResponse router = APIRouter(prefix="/students",tags=["学生信息管理模块"]) # 增加学生信息接口 @router.post("/",response_model=StudentResponse) def create_student_api( student_in: StudentCreate, db: Session = Depends(get_db) ): # 1. 校验外键:班级和顾问是否存在(与更新逻辑保持一致) if student_in.advisor_id is not None: advisor_exists = StudentDAO.inspect_advisor_id_unq(db, student_in.advisor_id) if not advisor_exists: raise HTTPException(status_code=400, detail="该顾问不存在") if student_in.class_id is not None: class_exists = StudentDAO.inspect_class_id_unq(db, student_in.class_id) if not class_exists: raise HTTPException(status_code=400, detail="该班级不存在") # 2. 校验通过后,直接调用 DAO 新增学生 student = StudentDAO.create_student(db=db, obj_in=student_in) return student # 查询所有学生接口 @router.get("/all", response_model=List[StudentResponse]) async def get_all_api( skip: int = Query(0, ge=0, description="跳过的记录数"), limit: int = Query(100, ge=1, le=200, description="返回的最大记录数"), db: Session = Depends(get_db) # 依赖注入获得数据库会话 ): students = StudentDAO.get_students_all(db, skip=skip, limit=limit) return students # FastAPI 自动根据 response_model 转换为 JSON # 多条件查询接口 @router.get("/search",response_model=List[StudentResponse]) async def get_multi_condition_api( stu_id: Optional[int] = Query(None, description="学生编号"), stu_name: Optional[str] = Query(None, description="学生姓名(支持模糊查询)"), class_id: Optional[int] = Query(None, description="班级编号"), skip: int = 0, limit: int = 100, db: Session = Depends(get_db) ): student = StudentDAO.query_multi_condition( db = db, stu_id = stu_id, stu_name = stu_name, class_id = class_id, skip = skip, limit = limit ) return student # # 根据id查询单个学生接口 # @router.get("/{stu_id}", response_model=StudentResponse) # async def get_student_by_id_api( # stu_id: int, # db: Session = Depends(get_db) # ): # student = StudentDAO.get_student_by_id(db=db, stu_id=stu_id) # if not student: # raise HTTPException(status_code=404, detail="用户不存在") # return student # 更改学生信息接口 @router.put("/{stu_id}",response_model=StudentResponse) async def update_student_api( stu_id: int, stu_update: StudentUpdate, db: Session = Depends(get_db) ): """更新学生信息,支持部分字段更新""" # 检查学生是否存在 existing = StudentDAO.get_student_by_id(db, stu_id) if not existing: raise HTTPException(status_code=404, detail="学生不存在") # 校验外键(班级和顾问是否存在) if stu_update.advisor_id is not None: advisor_exists = StudentDAO.inspect_advisor_id_unq(db, stu_update.advisor_id) if not advisor_exists: raise HTTPException(status_code=400, detail="该顾问不存在") if stu_update.class_id is not None: class_exists = StudentDAO.inspect_class_id_unq(db, stu_update.class_id) if not class_exists: raise HTTPException(status_code=400, detail="该班级不存在") # 直接调用 DAO 更新,学号不可改等逻辑已在 DAO 层处理 student = StudentDAO.update_student(db = db , stu_id = stu_id , obj = stu_update) return student # 逻辑删除接口:不返回完整学生实体,返回简单提示 @router.delete("/{stu_id}",status_code=204) async def delete_student_api( stu_id: int, db: Session = Depends(get_db) ): StudentDAO.delete_student(db, stu_id) # 返回 None 表示 204 状态码(无内容) return None