FastAPI 速通

FastAPI 速通

文章目录

入门

Hello World
python 复制代码
from fastapi import FastAPI

# 创建 FastAPI 实例
app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}

@app.get("/hello/{name}")
async def say_hello(name: str):
    return {"message": f"Hello {name}"}

文档接口/docs

路径、查询、请求体参数
python 复制代码
from fastapi import FastAPI, Path, Query
from pydantic import BaseModel, Field

app = FastAPI()

# ==========================================
# 1. 路径参数 (Path Parameters)
# 来源:URL 路径中的变量,如 /book/123
# 校验:Path(...) 用于校验数值范围、字符串长度等
# ==========================================

@app.get("/book/{id}")
async def get_book(id: int = Path(default=..., gt=0, lt=101, description="书籍id, 取值范围1-100")):
    return {"id": id, "title": f"这是第{id}本书"}

@app.get("/author/{name}")
async def get_author(name: str = Path(default=..., min_length=2, max_length=10)):
    return {"msg": f"这是{name}的信息"}

# ==========================================
# 2. 查询参数 (Query Parameters)
# 来源:URL ?后面的键值对,如 /news?skip=0&limit=10
# 校验:Query(...) 用于设置默认值、描述和限制
# ==========================================

@app.get("/news/news_list")
async def get_news_list(
    skip: int = Query(0, description="跳过的记录数", lt=100),
    limit: int = Query(10, description="返回的记录数")
):
    return {"skip": skip, "limit": limit}

# ==========================================
# 3. 请求体参数 (Request Body)
# 来源:POST/PUT 请求中的 JSON 数据
# 校验:Pydantic 模型 + Field(...)
# ==========================================

class User(BaseModel):
    username: str = Field(default="张三", min_length=2, max_length=10, description="用户名")
    password: str = Field(min_length=3, max_length=20)

@app.post("/register")
async def register(user: User):
    return user

# 默认路由
@app.get("/")
async def root():
    return {"message": "Hello World"}
响应类型、自定义响应数据格式
python 复制代码
from fastapi import FastAPI
from fastapi.responses import HTMLResponse, FileResponse
from pydantic import BaseModel

app = FastAPI()

# ==========================================
# 1. 响应 HTML 格式
# 关键点:response_class=HTMLResponse
# 作用:告诉 FastAPI 不要返回 JSON,而是直接返回 HTML 字符串
# ==========================================
@app.get("/html", response_class=HTMLResponse)
async def get_html():
    return "<h1>这是一级标题</h1>"

# ==========================================
# 2. 响应文件 (图片/文件下载)
# 关键点:FileResponse(path)
# 作用:自动处理文件流,设置正确的 Content-Type (如图片、PDF等)
# ==========================================
@app.get("/file")
async def get_file():
    # 注意:实际运行时请确保该路径下存在文件,否则会报错
    path = "./files/1.jpeg"
    return FileResponse(path)

# ==========================================
# 3. 自定义响应数据格式 (Pydantic)
# 关键点:class News(BaseModel) + response_model=News
# 作用:
#   1. 数据校验:确保返回的数据符合模型定义
#   2. 文档生成:在 Swagger UI 中展示清晰的响应模型结构
# ==========================================

# 定义数据模型
class News(BaseModel):
    id: int
    title: str
    content: str

# 使用模型
@app.get("/news/{id}", response_model=News)
async def get_news(id: int):
    # 这里的字典数据会被 Pydantic 自动转换为 News 对象并校验
    return {
        "id": id,
        "title": f"这是第{id}本书",
        "content": "这是一本好书"
    }

# 默认 JSON 响应
@app.get("/")
async def root():
    return {"message": "Hello World"}
中间件、依赖注入
python 复制代码
from fastapi import FastAPI, Query, Depends

app = FastAPI()

# ==========================================
# 1. 中间件 (Middleware)
# 执行顺序:自下而上(装饰器模式,先定义的在外层)
# 流程:中间件1 Start -> 中间件2 Start -> 路由处理 -> 中间件2 End -> 中间件1 End
# ==========================================

@app.middleware("http")
async def middleware_2(request, call_next):
    print("中间件2: 请求处理前 (内层)")
    response = await call_next(request) # 调用后续处理(路由或其他中间件)
    print("中间件2: 响应处理后 (内层)")
    return response

@app.middleware("http")
async def middleware_1(request, call_next):
    print("中间件1: 请求处理前 (外层)")
    response = await call_next(request)
    print("中间件1: 响应处理后 (外层)")
    return response

# ==========================================
# 2. 依赖注入 (Dependency Injection)
# 作用:代码复用(如分页、鉴权),逻辑与路由分离
# ==========================================

# 1. 定义依赖项(公共逻辑:分页参数)
async def common_pagination(
    skip: int = Query(0, ge=0, description="跳过数量"),
    limit: int = Query(10, le=60, description="限制数量")
):
    # 这里可以处理复杂的逻辑,最后返回结果
    return {"skip": skip, "limit": limit}

# 2. 路由中使用依赖注入
@app.get("/news/news_list")
async def get_news_list(pagination=Depends(common_pagination)):
    # 直接使用注入的结果
    return {"msg": "新闻列表", "params": pagination}

@app.get("/user/user_list")
async def get_user_list(pagination=Depends(common_pagination)):
    # 不同的路由复用同一个依赖项
    return {"msg": "用户列表", "params": pagination}

@app.get("/")
async def root():
    return {"message": "Hello World"}
ORM建表、路由中的使用
python 复制代码
from datetime import datetime
from fastapi import FastAPI, Depends
from sqlalchemy import DateTime, func, String, Float, select
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column

app = FastAPI()

# ==========================================
# 1. 数据库连接与建表配置 (公共底座)
# ==========================================

# 1.1 创建异步引擎
ASYNC_DATABASE_URL = "mysql+aiomysql://root:123456@localhost:3306/FastAPI_first?charset=utf8"
async_engine = create_async_engine(
    ASYNC_DATABASE_URL,
    echo=True,        # 输出SQL日志
    pool_size=10,     # 连接池大小
    max_overflow=20   # 额外连接数
)

# 1.2 定义基类 (包含公共时间字段)
class Base(DeclarativeBase):
    create_time: Mapped[datetime] = mapped_column(DateTime, default=func.now(), comment="创建时间")
    update_time: Mapped[datetime] = mapped_column(DateTime, default=func.now(), onupdate=func.now(), comment="修改时间")

# 1.3 定义具体模型 (书籍表)
class Book(Base):
    __tablename__ = "book"
    
    id: Mapped[int] = mapped_column(primary_key=True, comment="书籍id")
    bookname: Mapped[str] = mapped_column(String(255), comment="书名")
    author: Mapped[str] = mapped_column(String(255), comment="作者")
    price: Mapped[float] = mapped_column(Float, comment="价格")
    publisher: Mapped[str] = mapped_column(String(255), comment="出版社")

# 1.4 应用启动时自动建表
@app.on_event("startup")
async def startup_event():
    async with async_engine.begin() as conn:
        await conn.run_sync(Base.metadata.create_all)

# ==========================================
# 2. 路由中的使用 (依赖注入)
# ==========================================

# 2.1 创建会话工厂
AsyncSessionLocal = async_sessionmaker(
    bind=async_engine,
    class_=AsyncSession,
    expire_on_commit=False # 提交后对象不过期
)

# 2.2 定义依赖项 (核心:获取数据库连接 + 自动提交/回滚)
async def get_database():
    async with AsyncSessionLocal() as session:
        try:
            yield session        # 1. 提供给路由使用
            await session.commit() # 2. 无异常则提交
        except Exception:
            await session.rollback() # 3. 有异常则回滚
            raise
        finally:
            await session.close()  # 4. 最后关闭连接

# 2.3 路由示例:使用依赖注入查询数据
@app.get("/book/books")
async def get_book_list(db: AsyncSession = Depends(get_database)):
    # 执行查询语句
    result = await db.execute(select(Book))
    books = result.scalars().all() # 获取所有结果
    return books
数据库操作
python 复制代码
from datetime import datetime
from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy import DateTime, func, String, Float, select
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from pydantic import BaseModel

# ========== 公共底座(这部分通常只写一次,无需频繁修改)==========
app = FastAPI()

# 1. 数据库连接(引擎)
ASYNC_DATABASE_URL = "mysql+aiomysql://root:123456@localhost:3306/FastAPI_first?charset=utf8"
async_engine = create_async_engine(ASYNC_DATABASE_URL, echo=True, pool_size=10, max_overflow=20)

# 2. ORM 基类与模型
class Base(DeclarativeBase):
    create_time: Mapped[datetime] = mapped_column(DateTime, default=func.now(), comment="创建时间")
    update_time: Mapped[datetime] = mapped_column(DateTime, default=func.now(), onupdate=func.now(), comment="修改时间")

class Book(Base):
    __tablename__ = "book"
    id: Mapped[int] = mapped_column(primary_key=True, comment="书籍id")
    bookname: Mapped[str] = mapped_column(String(255), comment="书名")
    author: Mapped[str] = mapped_column(String(255), comment="作者")
    price: Mapped[float] = mapped_column(Float, comment="价格")
    publisher: Mapped[str] = mapped_column(String(255), comment="出版社")

# 3. 依赖项:获取数据库会话
AsyncSessionLocal = async_sessionmaker(bind=async_engine, class_=AsyncSession, expire_on_commit=False)

async def get_database():
    async with AsyncSessionLocal() as session:
        try:
            yield session
            await session.commit()
        except Exception:
            await session.rollback()
            raise
        finally:
            await session.close()

# 4. 启动事件:建表
@app.on_event("startup")
async def startup_event():
    async with async_engine.begin() as conn:
        await conn.run_sync(Base.metadata.create_all)

# ========== 核心业务逻辑 ==========
# 1. 查询数据 (Query)

# 需求:根据主键获取单条数据
@app.get("/book/get_book/{book_id}")
async def get_book(book_id: int, db: AsyncSession = Depends(get_database)):
    book = await db.get(Book, book_id) # 根据主键查询
    return book

# 需求:条件查询 (价格大于等于200)
@app.get("/book/search_price")
async def search_by_price(db: AsyncSession = Depends(get_database)):
    result = await db.execute(select(Book).where(Book.price >= 200))
    books = result.scalars().all()
    return books

# 需求:复杂条件 (模糊查询、逻辑运算、包含)
@app.get("/book/search_complex")
async def search_complex(db: AsyncSession = Depends(get_database)):
    # 模糊查询: 作者以"曹"开头;逻辑或: 价格大于100;包含: ID在列表中
    id_list = [1, 3, 5, 7]
    result = await db.execute(
        select(Book).where(
            (Book.author.like("曹%")) | 
            (Book.price > 100) | 
            (Book.id.in_(id_list))
        )
    )
    return result.scalars().all()

# 需求:聚合查询 (统计数量、最大值、求和、平均值)
@app.get("/book/stats")
async def get_stats(db: AsyncSession = Depends(get_database)):
    # count: 统计, max: 最大, sum: 求和, avg: 平均
    count = await db.execute(select(func.count(Book.id)))
    avg_price = await db.execute(select(func.avg(Book.price)))
    return {
        "total_count": count.scalar(),
        "average_price": avg_price.scalar()
    }

# 需求:分页查询
@app.get("/book/pagination")
async def get_paginated(page: int = 1, page_size: int = 3, db: AsyncSession = Depends(get_database)):
    skip = (page - 1) * page_size
    stmt = select(Book).offset(skip).limit(page_size)
    result = await db.execute(stmt)
    return result.scalars().all()

# 2. 新增数据 (Create)
class BookCreate(BaseModel):
    bookname: str
    author: str
    price: float
    publisher: str

@app.post("/book/add_book")
async def add_book(book: BookCreate, db: AsyncSession = Depends(get_database)):
    book_obj = Book(**book.dict()) # 将请求体数据转为ORM对象
    db.add(book_obj) # 添加到会话
    # 注意:commit在依赖项中统一处理了
    return {"msg": "新增成功", "data": book}

# 3. 更新数据 (Update)
class BookUpdate(BaseModel):
    bookname: str
    author: str
    price: float
    publisher: str

@app.put("/book/update_book/{book_id}")
async def update_book(book_id: int, data: BookUpdate, db: AsyncSession = Depends(get_database)):
    # 1. 查找
    db_book = await db.get(Book, book_id)
    if not db_book:
        raise HTTPException(status_code=404, detail="查无此书")
    
    # 2. 赋值修改
    db_book.bookname = data.bookname
    db_book.author = data.author
    db_book.price = data.price
    db_book.publisher = data.publisher
    # 提交在依赖项中处理
    return {"msg": "更新成功", "data": db_book}

# 4. 删除数据 (Delete)
@app.delete("/book/delete_book/{book_id}")
async def delete_book(book_id: int, db: AsyncSession = Depends(get_database)):
    db_book = await db.get(Book, book_id)
    if not db_book:
        raise HTTPException(status_code=404, detail="查无此书")
    
    await db.delete(db_book) # 删除对象
    return {"msg": "删除图书成功"}

实战

下面是教程所附项目后端设计说明文档,个人觉得非常优雅规范!因此附在此笔记中供日后温习。

AI掘金头条新闻系统 (Toutiao News)

一个基于 FastAPI 和 SQLAlchemy 构建的现代化新闻系统,支持用户注册登录、新闻浏览、收藏和历史记录等功能。

1-1 项目概述

这是一个仿今日头条的新闻系统后端API服务,采用异步Python框架FastAPI开发,使用MySQL作为数据库存储,通过SQLAlchemy ORM进行数据访问。系统提供完整的用户管理、新闻浏览、收藏和历史记录功能。

1-2 技术栈
  • 后端框架: FastAPI
  • 数据库: MySQL
  • ORM: SQLAlchemy (异步)
  • 数据库驱动: aiomysql
  • 密码加密: passlib + bcrypt
  • 缓存系统: Redis
  • 异步支持: Python asyncio
1-3 项目结构
复制代码
toutiao_backend/                          # 项目根目录
├── crud/                              # 数据访问层(CRUD操作)
│   ├── favorite.py                  # 收藏相关数据库操作
│   ├── history.py                   # 历史记录相关数据库操作
│   ├── news.py                      # 新闻相关数据库操作
│   └── users.py                     # 用户相关数据库操作
│
├── models/                            # 数据模型定义
│   ├── favorite.py                  # 收藏数据模型
│   ├── history.py                   # 历史记录数据模型
│   ├── news.py                      # 新闻数据模型
│   └── users.py                     # 用户数据模型
│
├── routers/                           # API路由定义
│   ├── favorite.py                  # 收藏相关API路由
│   ├── history.py                   # 历史记录相关API路由
│   ├── news.py                      # 新闻相关API路由
│   └── users.py                     # 用户相关API路由
│
├── schemas/                         # 数据验证模型(Pydantic模型)
│   ├── favorite.py                  # 收藏数据验证模型
│   ├── history.py                   # 历史记录数据验证模型
│   ├── news.py                      # 新闻数据验证模型
│   └── users.py                     # 用户数据验证模型
│
├── utils/                             # 工具函数目录
│
├── config/                             # 配置相关
│   ├── db_conf.py                    # 数据库配置文件
│   ├── cache_conf.py                 # Redis缓存配置
│ 
├── main.py                           # 应用入口文件
└── test_main.http                    # HTTP接口测试文件
1-4 功能模块

\1. 用户管理模块

  • 用户注册
  • 用户登录
  • 用户信息获取
  • 用户信息更新
  • 用户密码修改

\2. 新闻模块

  • 新闻分类获取
  • 新闻列表获取(支持分页和分类筛选)
  • 新闻详情获取
  • 浏览量统计

\3. 收藏模块

  • 添加收藏
  • 取消收藏
  • 收藏列表获取
  • 清空所有收藏
  • 检查收藏状态

\4. 浏览历史模块

  • 添加浏览记录
  • 浏览历史列表获取
  • 删除单条浏览记录
  • 清空浏览历史

\5. 缓存模块

  • 新闻详情缓存
  • 新闻列表缓存
  • 分类数据缓存
  • 用户历史记录缓存
1-5 数据库设计

主要数据表

  1. 用户表 (user)
    • 用户基本信息存储
    • 包含用户名、密码(加密)、昵称、头像等字段
  1. 用户令牌表 (user_token)
    • 用户认证令牌管理
    • 支持令牌过期机制
  1. 新闻分类表 (news_category)
    • 新闻分类信息
  1. 新闻表 (news)
    • 新闻内容存储
    • 包含标题、内容、作者、浏览量等字段
  1. 收藏表 (favorite)
    • 用户收藏记录
    • 关联用户和新闻
  1. 浏览历史表 (history)
    • 用户浏览历史记录
    • 关联用户和新闻
1-6 缓存设计

缓存策略

系统采用 Redis 作为缓存层,对高频访问的数据进行缓存,以提升系统性能和响应速度。

缓存数据类型

  1. 新闻详情缓存
    • 缓存键: news:detail:{news_id}
    • 过期时间: 1小时
    • 提升新闻详情页面访问速度
  1. 新闻列表缓存
    • 缓存键: news:list:{category_id}:{page}:{size}
    • 过期时间: 30分钟
    • 减少首页和分类页面的数据库查询压力
  1. 分类数据缓存
    • 缓存键: news:categories
    • 过期时间: 2小时
    • 加速导航栏分类数据加载
  1. 用户历史记录缓存
    • 缓存键: history:list:{user_id}
    • 过期时间: 1小时
    • 提高用户历史记录访问性能

缓存更新机制

  • 数据更新时自动清除相关缓存
  • 采用缓存失效而非主动更新策略
  • 支持批量清除特定模式的缓存

缓存配置

在 cache_conf.py 中配置 Redis 连接信息:

python 复制代码
REDIS_HOST = "localhost"
REDIS_PORT = 6379
REDIS_DB = 0
1-7 API 接口说明

用户相关接口

接口 方法 说明
/api/user/register POST 用户注册
/api/user/login POST 用户登录
/api/user/info GET 获取用户信息
/api/user/update PUT 更新用户信息
/api/user/password PUT 修改用户密码

新闻相关接口

接口 方法 说明
/api/news/categories GET 获取新闻分类列表
/api/news/list GET 获取新闻列表
/api/news/detail GET 获取新闻详情

收藏相关接口

接口 方法 说明
/api/favorite/check GET 检查新闻收藏状态
/api/favorite/add POST 添加收藏
/api/favorite/remove DELETE 取消收藏
/api/favorite/list GET 获取收藏列表
/api/favorite/clear DELETE 清空所有收藏

浏览历史相关接口

接口 方法 说明
/api/history/add POST 添加浏览记录
/api/history/list GET 获取浏览历史列表
/api/history/delete/{history_id} DELETE 删除单条浏览记录
/api/history/clear DELETE 清空浏览历史
1-8 认证机制

系统使用基于令牌(Token)的认证机制:

  1. 用户登录成功后返回访问令牌
  2. 需要认证的接口在请求头中添加 Authorization: token值
  3. 令牌有效期为7天
1-9 错误处理

系统提供统一的错误处理机制:

  • 用户认证失败返回 401 状态码
  • 资源不存在返回 404 状态码
  • 服务器内部错误返回 500 状态码
1-10 开发规范
  • 使用异步数据库操作
  • 所有密码均加密存储
  • 接口返回统一的 JSON 格式
  • 详细的接口文档和示例
  • 缓存操作封装成独立函数便于调用
1-11 性能优化
  • 使用 Redis 缓存热点数据
  • 异步数据库操作提升并发性能
  • 合理的数据库索引设计
  • 连接池管理减少连接开销
模块化路由、数据库和 ORM 配置
python 复制代码
# 模块化路由  
# 1. 在routers文件夹中对应路由文件中创建APIRouter实例
# 2. 在main.py中添加app.include_router()
# /routers/news.py
from fastapi import APIRouter

# 创建 APIRouter 实例
# prefix 路由前缀(API 接口规范文档)
# tags 分组 标签
router = APIRouter(prefix="/api/news", tags=["news"])

@router.get("/categories")
async def get_categories(skip: int = 0, limit: int = 100, db: AsyncSession = Depends(get_db)):
    categories = await news.get_categories(db, skip, limit)
    return {
        "code": 200,
        "message": "获取新闻分类成功",
        "data": categories
    }


# main.py
from fastapi import FastAPI
from routers import news, users

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}

# 挂载路由/注册路由
app.include_router(news.router)
app.include_router(users.router)


# 数据库和ORM配置
# 1. 安装SQLAlchemy pip install "sqlalchemy[asyncio]" aiomysql
# 2. ORM配置,放config文件夹中的db_conf.py中
from sqlalchemy.ext.asyncio import async_sessionmaker, AsyncSession, create_async_engine

# 数据库URL
ASYNC_DATABASE_URL = "mysql+aiomysql://root:123456@localhost:3306/news_app?charset=utf8mb4"

# 创建异步引擎
async_engine = create_async_engine(
    ASYNC_DATABASE_URL,
    echo=True, # 可选:输出SQL⽇志
    pool_size=10, # 设置连接池中保持的持久连接数
    max_overflow=20 # 设置连接池允许创建的额外连接数
)

# 创建异步会话⼯⼚
AsyncSessionLocal = async_sessionmaker(
    bind=async_engine,
    class_=AsyncSession,
    expire_on_commit=False
)

# 依赖项,⽤于获取数据库会话
async def get_db():
    async with AsyncSessionLocal() as session:
        try:
            yield session
            await session.commit()
            except Exception:
            await session.rollback()
        raise
        finally:
        await session.close()
接口实现完整流程
python 复制代码
# /routers/news.py
from fastapi import APIRouter, Depends, Query, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession

from config.db_conf import get_db
from crud import news

# 创建 APIRouter 实例
# prefix 路由前缀(API 接口规范文档)
# tags 分组 标签
router = APIRouter(prefix="/api/news", tags=["news"])

# 接口实现流程
# 1. 模块化路由 → API 接口规范文档
# 2. 定义模型类 → 数据库表(数据库设计文档)
# 3. 在 crud 文件夹里面创建文件,封装操作数据库的方法
# 4. 在路由处理函数里面调用 crud 封装好的方法,响应结果


@router.get("/categories")
async def get_categories(skip: int = 0, limit: int = 100, db: AsyncSession = Depends(get_db)):
    # 先获取数据库里面新闻分类数据 → 先定义模型类 → 封装查询数据的方法
    categories = await news.get_categories(db, skip, limit)
    return {
        "code": 200,
        "message": "获取新闻分类成功",
        "data": categories
    }


# main.py
from fastapi import FastAPI
from routers import news, users
from fastapi.middleware.cors import CORSMiddleware

from utils.exception_handlers import register_exception_handlers

app = FastAPI()

# 注册异常处理器
register_exception_handlers(app)


app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],     # 允许的源,开发阶段允许所有源,生产环境需要指定源
    allow_credentials=True,  # 允许携带cookie
    allow_methods=["*"],     # 允许的请求方法
    allow_headers=["*"],     # 允许的请求头
)


@app.get("/")
async def root():
    return {"message": "Hello World"}

# 挂载路由/注册路由
app.include_router(news.router)
app.include_router(users.router)


# /models/news.py
from datetime import datetime
from typing import Optional

from sqlalchemy import DateTime, Index, Text, ForeignKey
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from sqlalchemy import Integer, String


class Base(DeclarativeBase):
    created_at: Mapped[datetime] = mapped_column(
        DateTime,
        default=datetime.now,
        comment="创建时间"
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime,
        default=datetime.now,
        onupdate=datetime.now,
        comment="更新时间"
    )


class Category(Base):
    __tablename__ = "news_category"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True, comment="分类ID")
    name: Mapped[str] = mapped_column(String(50), unique=True, nullable=False, comment="分类名称")
    sort_order: Mapped[int] = mapped_column(Integer, default=0, nullable=False, comment="排序")

    def __repr__(self):
        return f"<Category(id={self.id}, name={self.name}, sort_order={self.sort_order})>"


# /crud/news.py
from sqlalchemy import select, func, update
from sqlalchemy.ext.asyncio import AsyncSession
from models.news import Category, News


async def get_categories(db: AsyncSession, skip: int = 0, limit: int = 100):
    stmt = select(Category).offset(skip).limit(limit)
    result = await db.execute(stmt)
    return result.scalars().all()

其他中间件的用法就不再写了,换汤不换药,本笔记用于快速熟悉 FastAPI 架构开发,之后复习到其他内容再总结用法

相关推荐
YMWM_2 小时前
export MPLBACKEND=Agg命令使用
linux·python
派大星~课堂2 小时前
【力扣-148. 排序链表】Python笔记
python·leetcode·链表
微涼5303 小时前
【Python】在使用联网工具时需要的问题
服务器·python·php
小白菜又菜3 小时前
Leetcode 657. Robot Return to Origin
python·leetcode·职场和发展
2402_881319303 小时前
跨服务通信兜底机制-Java 回传失败无持久重试队列,报告可能静默丢失。
java·开发语言·python
easyboot3 小时前
Visual Studio 2026安装Avalonia
ide·windows·visual studio
海市公约4 小时前
FastAPI入门实战:从零搭建到核心功能详解
fastapi·后端入门·异步编程·路由管理·python web开发·api设计·pydantic数据验证
自信不孤单4 小时前
UniAda核心代码详解
python·ai·大模型·tta·狄利克雷理论·证据感知
smj2302_796826524 小时前
解决leetcode第3883题统计满足数位和数组的非递减数组数目
python·算法·leetcode