目录
[1. common/result.py](#1. common/result.py)
[2. crud/news.py](#2. crud/news.py)
[3. routes/new.py](#3. routes/new.py)
1. common/result.py
python
from typing import Any
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel
# 统一接口返回结构
class Result(BaseModel):
code: int = 200
message: str = "success"
data: Any = None
@classmethod
def success(cls, data: Any = None, message: str = "success"):
# jsonable_encoder 会把 SQLAlchemy ORM 对象、datetime 等类型
# 转换成 FastAPI 可以正常返回的 JSON 数据
return cls(
code=200,
message=message,
data=jsonable_encoder(data)
)
@classmethod
def error(cls, message: str = "error", code: int = 500, data: Any = None):
# 失败响应统一走这里,方便前端按 code/message/data 处理
return cls(
code=code,
message=message,
data=jsonable_encoder(data)
)
2. crud/news.py
python
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.sql.expression import select
from models.news import Category
async def get_categories(db: AsyncSession, skip: int = 0, limit: int = 100):
"""
获取新闻分类
:param db: 数据库异步会话
:param skip: 跳过的数据条数,用于分页查询
:param limit: 每次查询的数据条数,用于分页查询
:return: 新闻分类 ORM 对象列表
"""
# 构建查询语句
# offset(skip):跳过前 skip 条数据
# limit(limit):最多查询 limit 条数据
stmt = select(Category).offset(skip).limit(limit)
# 执行异步 SQL 查询
result = await db.execute(stmt)
# scalars():取出 Category ORM 对象
# all():把查询结果转换成列表返回
return result.scalars().all()
3. routes/new.py
python
from fastapi import APIRouter
from fastapi.params import Depends
from sqlalchemy.ext.asyncio import AsyncSession
from common.result import Result
from crud import news
from config.db_confing import get_db
# 创建新闻模块路由
# prefix:当前文件下所有接口都会自动加上 /api/news 前缀
# tags:接口文档 Swagger 中显示的分组名称
router = APIRouter(prefix="/api/news", tags=["news"])
@router.get("/categories", response_model=Result)
async def get_categories(db: AsyncSession = Depends(get_db), skip: int = 0, limit: int = 100):
"""
获取新闻分类
:param db: 数据库异步会话
:param skip: 跳过的数据条数,用于分页查询
:param limit: 每次查询的数据条数,用于分页查询
:return: 统一格式的新闻分类列表响应
"""
# skip:跳过多少条数据;limit:最多返回多少条数据,用于分页查询
# 调用 crud 层查询新闻分类列表
categories = await news.get_categories(db, skip, limit)
# 使用统一返回对象,避免每个接口都手写 code/message/data
return Result.success(categories)