Merge pull request 'Li yujie' (#28) from LI_YUJIE into main
Reviewed-on: #28
This commit is contained in:
+89
-7
@@ -1,14 +1,96 @@
|
|||||||
from fastapi import APIRouter,Depends,HTTPException
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from dao.student import *
|
|
||||||
from schemas.student import StudentCreate
|
|
||||||
|
|
||||||
|
from core.database import get_db
|
||||||
|
from schemas.student import StudentCreate, StudentUpdate
|
||||||
|
from dao import student as student_dao
|
||||||
student_router = APIRouter()
|
student_router = APIRouter()
|
||||||
|
|
||||||
@student_router.post("/student")
|
@student_router.post("",summary='添加学生')
|
||||||
def create_student(request:StudentCreate,db:Session=Depends(create_students)):
|
def create_student(request:StudentCreate,db:Session = Depends(get_db)):
|
||||||
d = request.model_dump()
|
d = request.model_dump()
|
||||||
r = create_students(d,db)
|
r = student_dao.create_students(d,db)
|
||||||
if not r:
|
if not r:
|
||||||
raise HTTPException(status_code=500,detail='服务器繁忙,请稍后添加!')
|
raise HTTPException(status_code=500,detail='服务器繁忙,请稍后添加!')
|
||||||
return {'code':200,'detail':"添加学生成功"}
|
return {'code':200,'detail':"添加学生成功"}
|
||||||
|
|
||||||
|
@student_router.put("/{id}", summary="修改学生")
|
||||||
|
def update_student(
|
||||||
|
id: int,
|
||||||
|
request: StudentUpdate,
|
||||||
|
db: Session = Depends(get_db),
|
||||||
|
):
|
||||||
|
# 只取前端真正传来的字段
|
||||||
|
# 例如只传 age,就只修改 age
|
||||||
|
data = request.model_dump(exclude_unset=True)
|
||||||
|
|
||||||
|
student = student_dao.update_student(id, data, db)
|
||||||
|
|
||||||
|
# None 表示学生不存在
|
||||||
|
if student is None:
|
||||||
|
raise HTTPException(status_code=404, detail="学生不存在")
|
||||||
|
|
||||||
|
# False 表示操作数据库失败
|
||||||
|
if student is False:
|
||||||
|
raise HTTPException(status_code=500, detail="修改学生失败")
|
||||||
|
|
||||||
|
return {
|
||||||
|
"code": 200,
|
||||||
|
"detail": "修改学生成功",
|
||||||
|
"data": student,
|
||||||
|
}
|
||||||
|
|
||||||
|
@student_router.get("", summary="查询学生列表")
|
||||||
|
def get_students(
|
||||||
|
# 三个查询条件都可以不传
|
||||||
|
student_no: str | None = None,
|
||||||
|
student_name: str | None = None,
|
||||||
|
class_id: int | None = None,
|
||||||
|
# 获取本次请求使用的数据库连接
|
||||||
|
db: Session = Depends(get_db),
|
||||||
|
):
|
||||||
|
# 调用 DAO 查询数据库
|
||||||
|
students = student_dao.get_students(
|
||||||
|
db=db,
|
||||||
|
student_no=student_no,
|
||||||
|
student_name=student_name,
|
||||||
|
class_id=class_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"code": 200,
|
||||||
|
"detail": "查询成功",
|
||||||
|
"total": len(students),
|
||||||
|
"data": students,
|
||||||
|
}
|
||||||
|
|
||||||
|
@student_router.get("/{id}", summary="查询学生详情")
|
||||||
|
def get_student(id: int, db: Session = Depends(get_db)):
|
||||||
|
# 根据路径中的 ID 查询学生
|
||||||
|
student = student_dao.get_student_by_id(id, db)
|
||||||
|
|
||||||
|
if not student:
|
||||||
|
# 404 表示请求的数据不存在
|
||||||
|
raise HTTPException(status_code=404, detail="学生不存在")
|
||||||
|
|
||||||
|
return {
|
||||||
|
"code": 200,
|
||||||
|
"detail": "查询成功",
|
||||||
|
"data": student,
|
||||||
|
}
|
||||||
|
|
||||||
|
@student_router.delete("/{id}", summary="逻辑删除学生")
|
||||||
|
def delete_student(id: int, db: Session = Depends(get_db)):
|
||||||
|
student = student_dao.delete_student(id, db)
|
||||||
|
|
||||||
|
# None 表示不存在,或者以前已经删除
|
||||||
|
if student is None:
|
||||||
|
raise HTTPException(status_code=404, detail="学生不存在或已经删除")
|
||||||
|
|
||||||
|
if student is False:
|
||||||
|
raise HTTPException(status_code=500, detail="删除学生失败")
|
||||||
|
|
||||||
|
return {
|
||||||
|
"code": 200,
|
||||||
|
"detail": "删除学生成功",
|
||||||
|
}
|
||||||
|
|||||||
+93
-6
@@ -1,16 +1,103 @@
|
|||||||
from schemas.student import *
|
from schemas.student import *
|
||||||
from core.database import get_db
|
from core.database import get_db
|
||||||
from models.student import *
|
from models.student import *
|
||||||
from utils.code_generator import generate_no
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
|
|
||||||
def create_students(d,db):
|
def create_students(d: dict, db: Session):
|
||||||
stu = Student(**d)
|
stu = Student(**d)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
db.add(stu)
|
db.add(stu)
|
||||||
generate_no("student_no", "STU", stu, db)
|
# 把 SQL 发给数据库执行
|
||||||
|
db.flush()
|
||||||
|
# 根据 id 生成学生编号
|
||||||
|
if not stu.student_no:
|
||||||
|
stu.student_no = f"STU{stu.id:04d}"
|
||||||
db.commit()
|
db.commit()
|
||||||
except:return False
|
db.refresh(stu)
|
||||||
else:
|
return stu
|
||||||
return True
|
except Exception as e:
|
||||||
|
db.rollback()
|
||||||
|
print(f"插入学生失败: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_student_by_id(student_id: int, db: Session):
|
||||||
|
# 同时判断 is_deleted,已经逻辑删除的学生不会被查到
|
||||||
|
return db.query(Student).filter(
|
||||||
|
Student.id == student_id,
|
||||||
|
Student.is_deleted == 0,
|
||||||
|
).first()
|
||||||
|
|
||||||
|
def update_student(student_id: int, data: dict, db: Session):
|
||||||
|
# 第一步:先查询学生
|
||||||
|
student = get_student_by_id(student_id, db)
|
||||||
|
|
||||||
|
# 没有查到就返回 None
|
||||||
|
if not student:
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 第二步:循环修改前端传来的字段
|
||||||
|
# field 是字段名,value 是新的值
|
||||||
|
for field, value in data.items():
|
||||||
|
setattr(student, field, value)
|
||||||
|
|
||||||
|
# 第三步:提交修改并重新读取数据
|
||||||
|
db.commit()
|
||||||
|
db.refresh(student)
|
||||||
|
return student
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
# 修改失败时回滚
|
||||||
|
db.rollback()
|
||||||
|
print("修改学生失败:", e)
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_students(
|
||||||
|
db: Session,
|
||||||
|
student_no: str | None = None,
|
||||||
|
student_name: str | None = None,
|
||||||
|
class_id: int | None = None,
|
||||||
|
):
|
||||||
|
# 第一步:只查询没有被删除的学生
|
||||||
|
query = db.query(Student).filter(Student.is_deleted == 0)
|
||||||
|
|
||||||
|
# 第二步:前端传了哪个条件,就增加哪个条件
|
||||||
|
if student_no:
|
||||||
|
# 学号使用精确查询
|
||||||
|
query = query.filter(Student.student_no == student_no)
|
||||||
|
|
||||||
|
if student_name:
|
||||||
|
# 姓名使用模糊查询,例如“张”可以查到“张三”
|
||||||
|
query = query.filter(Student.student_name.like(f"%{student_name}%"))
|
||||||
|
|
||||||
|
if class_id:
|
||||||
|
# 班级 ID 使用精确查询
|
||||||
|
query = query.filter(Student.class_id == class_id)
|
||||||
|
|
||||||
|
# 第三步:执行查询并返回全部结果
|
||||||
|
return query.all()
|
||||||
|
|
||||||
|
#逻辑删除学生
|
||||||
|
def delete_student(student_id: int, db: Session):
|
||||||
|
# 第一步:查询学生
|
||||||
|
student = get_student_by_id(student_id, db)
|
||||||
|
|
||||||
|
if not student:
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 第二步:不真正删除记录,只把删除标记改成 1
|
||||||
|
student.is_deleted = 1
|
||||||
|
|
||||||
|
# 第三步:提交修改
|
||||||
|
db.commit()
|
||||||
|
return student
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
# 删除失败时回滚
|
||||||
|
db.rollback()
|
||||||
|
print("删除学生失败:", e)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -10,4 +10,4 @@ engine = create_engine(db_url
|
|||||||
|
|
||||||
Base.metadata.create_all(engine)
|
Base.metadata.create_all(engine)
|
||||||
db = SessionLocal()
|
db = SessionLocal()
|
||||||
db.commit()
|
db.commit() #创建全部表
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from api.example import example_router
|
from api.example import example_router
|
||||||
from middleware import log_middleware
|
from middleware import log_middleware
|
||||||
from api.statistics import statistics_router
|
# from api.statistics import statistics_router
|
||||||
import uvicorn
|
import uvicorn
|
||||||
from api.student import student_router
|
from api.student import student_router
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
@@ -12,15 +12,15 @@ from api.class_api import classes_router
|
|||||||
app.include_router(classes_router,tags=['班级接口'],prefix="/classes")
|
app.include_router(classes_router,tags=['班级接口'],prefix="/classes")
|
||||||
|
|
||||||
#-------------李玉杰--------------
|
#-------------李玉杰--------------
|
||||||
app.include_router(student_router)
|
app.include_router(student_router,tags=['学生接口'],prefix="/students")
|
||||||
#-------------张义---------------
|
#-------------张义---------------
|
||||||
|
|
||||||
#-------------薄鑫---------------
|
#-------------薄鑫---------------
|
||||||
from api import consultant
|
from api import consultant
|
||||||
app.include_router(consultant.router)
|
app.include_router(consultant.router)
|
||||||
#-------------张昕浩---------------
|
#-------------张昕浩---------------
|
||||||
app.include_router(example_router)
|
# app.include_router(example_router)
|
||||||
app.include_router(statistics_router, prefix="/statistics")
|
# app.include_router(statistics_router, prefix="/statistics")
|
||||||
|
|
||||||
#-------------曾凯---------------
|
#-------------曾凯---------------
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -10,7 +10,8 @@ class Student(Base):
|
|||||||
, comment = '学生编号,自增主键'
|
, comment = '学生编号,自增主键'
|
||||||
)
|
)
|
||||||
student_no = Column(VARCHAR(50)
|
student_no = Column(VARCHAR(50)
|
||||||
, unique = True)
|
,nullable = True
|
||||||
|
,unique = True)
|
||||||
student_name = Column(VARCHAR(50))
|
student_name = Column(VARCHAR(50))
|
||||||
class_id = Column(Integer
|
class_id = Column(Integer
|
||||||
,ForeignKey('class_info_detail.id')
|
,ForeignKey('class_info_detail.id')
|
||||||
|
|||||||
+32
-10
@@ -1,18 +1,40 @@
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
||||||
|
|
||||||
class StudentCreate(BaseModel):
|
class StudentCreate(BaseModel):
|
||||||
student_no: str|None = None
|
student_no: str | None = Field(default=None, min_length=1, max_length=50)
|
||||||
student_name: str
|
student_name: str = Field(min_length=1, max_length=50)
|
||||||
class_id: int
|
class_id: int = Field(gt=0)
|
||||||
consultant_id: int | None = None
|
consultant_id: int | None = Field(default=None, gt=0)
|
||||||
native_place: str | None = None
|
native_place: str | None = Field(default=None, max_length=100)
|
||||||
graduate_school: str | None = None
|
graduation_school: str | None = Field(default=None, max_length=100)
|
||||||
major: str | None = None
|
major: str | None = Field(default=None, max_length=100)
|
||||||
enrollment_date: date
|
enrollment_date: date
|
||||||
graduation_date: date | None = None
|
graduation_date: date | None = None
|
||||||
|
education: str | None = Field(default=None, max_length=50)
|
||||||
|
age: int = Field(ge=0, le=150)
|
||||||
|
gender: str = Field(min_length=1, max_length=10)
|
||||||
|
|
||||||
|
@model_validator(mode="after")
|
||||||
|
def check_dates(self):
|
||||||
|
# 3. 新增时两个日期都已确定,可以直接校验先后顺序。
|
||||||
|
if self.graduation_date and self.graduation_date < self.enrollment_date:
|
||||||
|
raise ValueError("毕业日期不能早于入学日期")
|
||||||
|
return self
|
||||||
|
|
||||||
|
class StudentUpdate(BaseModel):
|
||||||
|
# 全部设为可选,前端只传需要修改的字段
|
||||||
|
student_no: str | None = None
|
||||||
|
student_name: str | None = None
|
||||||
|
class_id: int | None = None
|
||||||
|
consultant_id: int | None = None
|
||||||
|
native_place: str | None = None
|
||||||
|
graduation_school: str | None = None
|
||||||
|
major: str | None = None
|
||||||
|
enrollment_date: date | None = None
|
||||||
|
graduation_date: date | None = None
|
||||||
education: str | None = None
|
education: str | None = None
|
||||||
age: int
|
age: int | None = None
|
||||||
gender: str
|
gender: str | None = None
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ def add_student(
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
def generate_no(field_name: str, prefix: str, db_object, db):
|
def generate_no(field_name: str, prefix: str, db_object, db: Session):
|
||||||
if getattr(db_object, field_name):
|
if getattr(db_object, field_name):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user