系列文章目录
《FastAPI零基础入门与进阶实战》https://blog.csdn.net/sen_shan/category_12950843.html第11篇:ORM之第一个案例
https://blog.csdn.net/sen_shan/article/details/147498244?spm=1011.2415.3001.5331
文章目录
前言
模块化路由是将应用的路由逻辑按照功能模块进行划分,每个模块负责处理特定的业务逻辑。这种设计方式不仅使代码结构更加清晰,还便于团队协作和代码复用。通过将不同的功能模块化,开发者可以专注于各自的功能实现,而不会被复杂的路由逻辑所困扰。
模块化路由管理
在 src 目录下新增 router 文件夹,并在其中创建 sys_user.py 文件。
# src/router/sys_user.py
# from main import startup_event, shutdown_event
from src.crud import sys_user as crud
from src.schemas import sys_user as schemas
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from src.core.ormdb import get_db
router = APIRouter( # prefix="/user",
# tags=["sys_user"] # ,
# dependencies=[Depends(get_token_header)],
# responses={404: {"description": "Not found"}},
# description="Operations related to system users",
# on_startup=[startup_event],
# on_shutdown=[shutdown_event]
)
# 创建用户
@router.post("/users/", response_model=list[schemas.SysUser])
def create_users(users: list[schemas.SysUserCreate], db: Session = Depends(get_db)):
return crud.create_users(db, users)
@router.post("/user/", response_model=schemas.SysUser)
def create_user(user: schemas.SysUserCreate, db: Session = Depends(get_db)):
return crud.create_user(db, user)
# 获取用户
@router.get("/users/{user_id}", response_model=schemas.SysUser)
def read_user(user_id: str, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
# 获取所有用户
@router.get("/users/", response_model=list[schemas.SysUser])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
return crud.get_users(db, skip, limit)
# 更新用户
@router.put("/users/{user_id}", response_model=schemas.SysUser)
def update_user(user_id: str, user: schemas.SysUserCreate, db: Session = Depends(get_db)):
db_user = crud.update_user(db, user_id, user)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
# 删除用户
@router.delete("/users/{user_id}")
def delete_user(user_id: str, db: Session = Depends(get_db)):
db_user = crud.delete_user(db, user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return {"message": "User deleted"}
功能概述
本模块是一个 FastAPI 路由器,用于管理系统用户(`sys_user`)的增删改查操作。它通过依赖注入的方式与数据库会话(`Session`)和数据操作层(`crud`)进行交互,实现了用户数据的高效管理和操作。
主要功能
• 创建用户
• 批量创建用户:
• 路径:`POST /users/`
• 输入:用户列表(`list[schemas.SysUserCreate]`)
• 输出:创建的用户列表(`list[schemas.SysUser]`)
• 功能:接收用户列表并批量创建用户。
• 创建单个用户:
• 路径:`POST /user/`
• 输入:单个用户信息(`schemas.SysUserCreate`)
• 输出:创建的用户信息(`schemas.SysUser`)
• 功能:创建单个用户。
• 获取用户
• 按 ID 获取用户:
• 路径:`GET /users/{user_id}`
• 输入:用户 ID(`user_id: str`)
• 输出:用户信息(`schemas.SysUser`)
• 功能:根据用户 ID 查询用户信息,若用户不存在则返回 404 错误。
• 获取所有用户:
• 路径:`GET /users/`
• 输入:分页参数(`skip: int`,`limit: int`)
• 输出:用户列表(`list[schemas.SysUser]`)
• 功能:获取所有用户信息,支持分页查询。
• 更新用户
• 更新用户信息:
• 路径:`PUT /users/{user_id}`
• 输入:用户 ID(`user_id: str`)和更新后的用户信息(`schemas.SysUserCreate`)
• 输出:更新后的用户信息(`schemas.SysUser`)
• 功能:根据用户 ID 更新用户信息,若用户不存在则返回 404 错误。
• 删除用户
• 删除用户:
• 路径:`DELETE /users/{user_id}`
• 输入:用户 ID(`user_id: str`)
• 输出:操作结果(`{"message": "User deleted"}`)
• 功能:根据用户 ID 删除用户,若用户不存在则返回 404 错误。
配置选项(注释部分)
• 路由前缀:可配置为`/user`。
• 路由标签:可设置为`["sys_user"]`,便于 API 文档分类。
• 依赖项:可添加额外的依赖项,例如`Depends(get_token_header)`。
• 启动和关闭事件:可设置`on_startup`和`on_shutdown`事件,用于初始化和清理操作。
软件包定义
在 src 文件夹在 __init__.py 文件中增加sysUserRouter
,具体内容如下:
# src/__init__.py
from src.core import load_config, Config, str_utils
from src.core.logging_utils import logger_cust
from src.core import global_data
from src.models.login_manager import LoginManager
from src.core import dependencies,security
from src.models import login_manager
from src.core import crypt_utils
from src.core import db_utils
from src.core import retMes
from src.core.ormdb import engine, SessionLocal, Base
from src.models.sys_user import SysUser
from src.router.sys_user import router as sysUserRouter
__all__ = ['load_config',
'Config',
'str_utils',
'logger_cust',
'global_data',
'LoginManager',
'dependencies',
'login_manager',
'retMes',
'security',
'crypt_utils',
'engine',
'SessionLocal',
'Base',
'db_utils',
'SysUser',
'sysUserRouter'
]
# 初始化代码
路由集成
移除原有的用户API实现,通过 include_router 方法集成用户路由模块
app.include_router(sysUserRouter, prefix="", tags=["User API"], include_in_schema=True)
完整代码:
#main.py
from email.policy import default
from typing import Optional
from fastapi import FastAPI, Request, Depends, Header, HTTPException
from fastapi import APIRouter
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from src import Config, logger_cust, global_data, LoginManager, dependencies, login_manager
from src.services.user import login
from fastapi.middleware.cors import CORSMiddleware
from src import Base, SessionLocal, engine
from src import sysUserRouter
app = FastAPI()
# 定义允许的跨域源列表
origins = [
"http://localhost", # 允许来自 http://localhost 的请求
"http://localhost:8080", # 允许来自 http://localhost:8080 的请求
"http://localhost:5173", # 允许来自 http://localhost:5173 的请求
"https://example.com", # 允许来自 https://example.com 的请求
]
# 添加 CORS 中间件
app.add_middleware(
CORSMiddleware,
allow_origins=origins, # 允许的源列表
allow_credentials=True, # 允许携带身份凭证(如 Cookies)
allow_methods=["*"], # 允许所有 HTTP 方法
allow_headers=["*"], # 允许所有请求头
)
# 定义一个依赖项列表
# dependencies = [Depends(dependencies.auth_api_key), Depends(dependencies.auth_token)]
# dependencies = [Depends(dependencies.auth_api_key)]
# dependencies_api_key = [Depends(dependencies.auth_api_key)]
@app.on_event("startup")
async def startup_event():
# 创建数据库表
Base.metadata.create_all(bind=engine)
# 初始化全局资源,例如数据库连接、配置加载等
# 示例:await database.connect()
@app.on_event("shutdown")
async def shutdown_event():
print("Main application is shutting down")
# 清理全局资源,例如关闭数据库连接等
# 示例:await database.disconnect()
app.include_router(sysUserRouter, prefix="", tags=["User API"], include_in_schema=True)
@app.get("/")
async def read_root(app_manager: Optional[dict] = Depends(dependencies.auth_api_key),
app_id: Optional[dict] = Depends(dependencies.auth_api_key)):
return {"message": "Hello World", "app_manager": app_manager}
@app.post("/login")
async def regLogin(login_data: login_manager.LoginRequest,
app_manager: Optional[dict] = Depends(dependencies.auth_api_key)):
retMes = login.login(login_data, app_manager)
# print(login.loginInfo.get())
return retMes # {"access_token": login_data, "app_id": app_id}
# 使用依赖项
@app.get("/items")
async def read_items(auth: dict = Depends(dependencies.auth_token)):
return auth
@app.get("/headers")
async def get_headers(request: Request):
headers = request.headers
return {"headers": dict(headers)}
# 创建用户
应用启动和关闭事件•
在应用启动时( startup_event ):
• 创建数据库表( Base.metadata.create_all )。
• 可以初始化全局资源,例如加载配置文件、连接数据库等。
• 在应用关闭时( shutdown_event ):
• 可以清理全局资源,例如关闭数据库连接等。
路由集成
• 使用 include_router 方法将用户路由模块( sysUserRouter )集成到主应用中,设置路由前缀为空( prefix="" ),并将其标记为“User API”。
批量创建用户
在 crud/sys_user.py 文件中新增以下代码:
def create_users(db: Session, users: list[schemas.SysUserCreate]):
try:
db_users = [models.SysUser(**user.dict()) for user in users]
db.add_all(db_users)
db.commit()
for db_user in db_users:
db.refresh(db_user)
return db_users
except Exception as e:
db.rollback()
raise e
完整代码如下:
# crud/sys_user.py
from sqlalchemy.orm import Session
from src.models import sys_user as models
from src.schemas import sys_user as schemas
def create_user(db: Session, user: schemas.SysUserCreate):
db_user = models.SysUser(**user.dict())
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
def create_users(db: Session, users: list[schemas.SysUserCreate]):
try:
db_users = [models.SysUser(**user.dict()) for user in users]
db.add_all(db_users)
db.commit()
for db_user in db_users:
db.refresh(db_user)
return db_users
except Exception as e:
db.rollback()
raise e
def get_user(db: Session, user_id: str):
return db.query(models.SysUser).filter(models.SysUser.id == user_id).first()
def get_users(db: Session, skip: int = 0, limit: int = 100):
return db.query(models.SysUser).offset(skip).limit(limit).all()
def update_user(db: Session, user_id: str, user: schemas.SysUserCreate):
db_user = db.query(models.SysUser).filter(models.SysUser.id == user_id).first()
if db_user is None:
return None
db_user.api_id = user.api_id
db_user.login_id = user.login_id
db_user.user_name = user.user_name
db_user.login_password = user.login_password
db_user.email = user.email
db_user.person_id = user.person_id
db_user.is_superuser = user.is_superuser
db_user.is_staff = user.is_staff
db_user.effective_date = user.effective_date
db_user.expiry_date = user.expiry_date
db_user.deletion_mark = user.deletion_mark
db_user.deletion_reason = user.deletion_reason
db_user.deletion_date = user.deletion_date
db_user.deletion_by = user.deletion_by
db_user.creator_by = user.creator_by
db_user.last_updated_date = user.last_updated_date
db_user.last_updated_by = user.last_updated_by
db.commit()
db.refresh(db_user)
return db_user
def delete_user(db: Session, user_id: str):
db_user = db.query(models.SysUser).filter(models.SysUser.id == user_id).first()
if db_user is None:
return None
db.delete(db_user)
db.commit()
return db_user
验证测试
运行后,请访问以下网址:http://127.0.0.1:8080/docs#/
使用APIPOST工具新增多用户信息时,请访问以下API地址: http://127.0.0.1:8080/users/
测试资料:
[
{
"id": "1",
"api_id": "123",
"login_id": "alice",
"user_name": "Alice",
"login_password": "password123",
"email": "alice@example.com",
"person_id": "P001",
"is_superuser": false,
"is_staff": true,
"effective_date": "2023-01-01",
"expiry_date": "2025-12-31",
"deletion_mark": false,
"deletion_reason": null,
"deletion_date": null,
"deletion_by": null,
"creator_by": "admin",
"last_updated_date": "2023-01-01",
"last_updated_by": "admin"
},
{
"id": "2",
"api_id": "456",
"login_id": "bob",
"user_name": "Bob",
"login_password": "password456",
"email": "bob@example.com",
"person_id": "P002",
"is_superuser": false,
"is_staff": false,
"effective_date": "2023-02-01",
"expiry_date": "2025-12-31",
"deletion_mark": false,
"deletion_reason": null,
"deletion_date": null,
"deletion_by": null,
"creator_by": "admin",
"last_updated_date": "2023-02-01",
"last_updated_by": "admin"
},
{
"id": "3",
"api_id": "789",
"login_id": "charlie",
"user_name": "Charlie",
"login_password": "password789",
"email": "charlie@example.com",
"person_id": "P003",
"is_superuser": true,
"is_staff": true,
"effective_date": "2023-03-01",
"expiry_date": "2025-12-31",
"deletion_mark": false,
"deletion_reason": null,
"deletion_date": null,
"deletion_by": null,
"creator_by": "admin",
"last_updated_date": "2023-03-01",
"last_updated_by": "admin"
}
]
输出结果:
[
{
"api_id": "123",
"login_id": "alice",
"user_name": "Alice",
"login_password": "password123",
"email": "alice@example.com",
"person_id": "P001",
"is_superuser": false,
"is_staff": true,
"effective_date": "2023-01-01",
"expiry_date": "2025-12-31",
"deletion_mark": false,
"deletion_reason": null,
"deletion_date": null,
"deletion_by": null,
"creator_by": "admin",
"last_updated_date": "2023-01-01T00:00:00",
"last_updated_by": "admin",
"id": "bc29006b-e0f4-42c1-a8a6-747baa5ce3a2"
},
{
"api_id": "456",
"login_id": "bob",
"user_name": "Bob",
"login_password": "password456",
"email": "bob@example.com",
"person_id": "P002",
"is_superuser": false,
"is_staff": false,
"effective_date": "2023-02-01",
"expiry_date": "2025-12-31",
"deletion_mark": false,
"deletion_reason": null,
"deletion_date": null,
"deletion_by": null,
"creator_by": "admin",
"last_updated_date": "2023-02-01T00:00:00",
"last_updated_by": "admin",
"id": "1154b448-91b3-44d0-b170-0efcb25617f3"
},
{
"api_id": "789",
"login_id": "charlie",
"user_name": "Charlie",
"login_password": "password789",
"email": "charlie@example.com",
"person_id": "P003",
"is_superuser": true,
"is_staff": true,
"effective_date": "2023-03-01",
"expiry_date": "2025-12-31",
"deletion_mark": false,
"deletion_reason": null,
"deletion_date": null,
"deletion_by": null,
"creator_by": "admin",
"last_updated_date": "2023-03-01T00:00:00",
"last_updated_by": "admin",
"id": "4817eb5a-c6e3-4e4d-937e-7373a7f7e3fa"
}
]