# fastapi-study **Repository Path**: learning-python_1/fastapi-study ## Basic Information - **Project Name**: fastapi-study - **Description**: Python的MVC框架 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-01-18 - **Last Updated**: 2026-01-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # FastAPI 学习笔记 ## 项目概述 本项目是一个 FastAPI 框架的学习项目,涵盖了从基础入门到实际应用的完整学习路径。项目使用 Python 3.x,主要依赖包括 FastAPI、SQLAlchemy、SQLModel、Uvicorn 等。 ### 主要依赖 - `fastapi==0.124.0` - FastAPI 框架 - `uvicorn==0.38.0` - ASGI 服务器 - `sqlmodel==0.0.27` - SQL 模型框架 - `sqlalchemy==2.0.44` - ORM 框架 - `pydantic==2.12.5` - 数据验证框架 - `pymysql==1.1.2` - MySQL 数据库驱动 --- ## 第一章:Web 入门 (ch01) ### 学习目标 了解 FastAPI 的基本使用,创建第一个 Web 应用。 ### 核心知识点 1. **FastAPI 应用创建** ```python from fastapi import FastAPI app = FastAPI() ``` 2. **路由装饰器** - `@app.get("/")` - 处理 GET 请求 - 使用 `async def` 定义异步处理函数 3. **启动服务器** ```python uvicorn.run(app, host="127.0.0.1", port=8000) ``` ### 关键特性 - FastAPI 自动生成 API 文档,访问 `http://127.0.0.1:8000/docs` 可查看 Swagger UI - 支持异步处理,提高性能 - 自动数据验证和序列化 ### 代码示例 ```python @app.get("/") async def root(): return {"message": "Hello World"} ``` --- ## 第二章:访问静态资源 (ch02) ### 学习目标 学习如何在 FastAPI 中挂载和访问静态文件。 ### 核心知识点 1. **静态文件挂载** ```python from starlette.staticfiles import StaticFiles app.mount("/page", StaticFiles(directory="static")) ``` - `/page` 是虚拟请求地址 - `StaticFiles` 用于映射本地资源目录 - `directory="static"` 指定静态文件目录 ### 使用场景 - 提供 HTML、CSS、JavaScript 等前端资源 - 提供图片、文档等静态文件 - 构建前后端分离的应用 --- ## 第三章:FastAPI 装饰器(请求方式)(ch03) ### 学习目标 掌握 FastAPI 中不同 HTTP 请求方法的处理。 ### 核心知识点 1. **HTTP 方法装饰器** - `@app.get("/")` - GET 请求 - `@app.post("/")` - POST 请求 - `@app.put("/")` - PUT 请求 - `@app.delete("/")` - DELETE 请求 2. **装饰器参数** - `tags=["标签名"]` - 接口分组标签 - `summary="接口标题"` - 接口简要说明 - `description="详细描述"` - 接口详细说明 - `response_description="响应说明"` - 响应内容说明 - `deprecated=False` - 是否废弃接口 ### 代码示例 ```python @app.get("/user", tags=["用户信息查询接口"], summary="根据ID查询详细的用户信息", description="查询详细的说明", response_description="响应内容的详细说明", deprecated=False) def get_user(): return {"data": "张三"} ``` ### 最佳实践 - 使用 `tags` 对接口进行分组,便于在 Swagger UI 中查看 - 提供清晰的 `summary` 和 `description`,提高 API 文档可读性 --- ## 第四章:路由 (ch04) ### 学习目标 学习如何组织和管理多个路由,实现模块化开发。 ### 核心知识点 1. **APIRouter 创建子路由** ```python from fastapi import APIRouter user = APIRouter() ``` 2. **路由注册** ```python app.include_router(user, prefix="/user", tags=["用户中心接口"]) ``` - `prefix` - 路由前缀 - `tags` - 接口标签 ### 项目结构 ``` ch04/ ├── main.py # 主入口,注册所有路由 ├── user_api.py # 用户相关接口 └── order_api.py # 订单相关接口 ``` ### 优势 - **模块化开发**:不同功能模块分离 - **代码组织**:便于维护和扩展 - **团队协作**:多人可并行开发不同模块 --- ## 第五章:请求参数 (ch05) ### 学习目标 掌握如何接收和处理不同类型的请求参数。 ### 核心知识点 1. **Request 对象** ```python from fastapi import Request @app.get("/request") async def test(request: Request): print("请求url:", request.url) print("客户端请求地址:", request.client.host) print("请求头:", request.headers) print("cookies:", request.cookies) print("查询参数", request.query_params) ``` 2. **查询参数映射** ```python @app.get("/user") async def get_user(name: str = '', age: int = 0) -> dict: return {"name": name, "age": age} ``` 3. **路径参数** ```python @app.get("/users/{u_id}") async def get_user_by_id(u_id: int) -> dict: return {"u_id": u_id} ``` - 路径参数名必须与函数参数名一致 4. **请求体参数(Pydantic 模型)** ```python @app.post("/user") async def add_user(user: User) -> dict: return {"message": "success"} ``` ### 数据验证(Pydantic) ```python from pydantic import BaseModel, Field, field_validator class User(BaseModel): name: str = Field(default="", max_length=20, description="名字长度不能超过20个字符") age: int = Field(default=0, gt=18, lt=60, description="年龄必须大于18并且小于60岁") @field_validator("name", mode="after") def valid_name(cls, name: str) -> str: if name != "zhangsan": raise ValueError("用户不存在") return name ``` ### 参数类型 - **查询参数**:URL 中的 `?key=value` 形式 - **路径参数**:URL 路径中的变量,如 `/users/{id}` - **请求体参数**:POST/PUT 请求的 JSON 数据 - **请求头参数**:通过 `Header()` 获取 - **Cookie 参数**:通过 `Cookie()` 获取 --- ## 第六章:响应模型 (ch06) ### 学习目标 学习如何控制 API 响应数据的格式和内容。 ### 核心知识点 1. **响应模型设置** ```python @app.get("/user/{id}", response_model=UserVO) async def get_user(id: int): user = User(name="张三", password="123456", age=21) return user ``` 2. **响应模型参数** - `response_model` - 指定响应视图对象 - `response_model_include={"属性名"}` - 包含(保留)要显示的属性 - `response_model_exclude={"属性名"}` - 排除某些属性 - `response_model_exclude_unset=True` - 排除未设值的属性 - `response_model_exclude_defaults=True` - 排除默认值的属性 - `response_model_exclude_none=True` - 排除值为 None 的属性 ### 使用场景 - **数据脱敏**:隐藏敏感信息(如密码) - **视图对象(VO)**:返回给前端的数据结构 - **数据转换**:将数据库模型转换为展示模型 ### 代码示例 ```python class User(BaseModel): name: str password: str age: int class UserVO(BaseModel): name: str age: int # 不包含 password 字段 ``` ### 注意事项 响应模型具备拷贝功能,当 `response_model` 指定的是其他对象或 VO 时,装饰器会将返回的对象拷贝到 `response_model` 指定的 VO 中。 --- ## 第七章:中间件(Java 拦截器)(ch07) ### 学习目标 学习如何使用中间件在请求处理前后进行拦截和处理。 ### 核心知识点 1. **中间件定义** ```python @app.middleware("http") async def add_process(request: Request, call_next): print("请求处理前...") response = await call_next(request) print("请求处理后...") return response ``` 2. **中间件执行顺序** - 多个中间件按定义顺序执行 - 请求处理前:按定义顺序执行 - 请求处理后:按相反顺序执行 ### 使用场景 - **日志记录**:记录请求和响应信息 - **性能监控**:计算请求处理时间 - **权限验证**:统一验证用户权限 - **请求转换**:修改请求或响应数据 - **异常处理**:统一处理异常 ### 代码示例 ```python @app.middleware("http") async def add_process(request: Request, call_next): print("请求处理前1...") response = await call_next(request) print("请求处理后1...") return response @app.middleware("http") async def add_process2(request: Request, call_next): print("请求处理前2...") response = await call_next(request) print("请求处理后2...") return response ``` ### 执行流程 ``` 请求 → 中间件1(前) → 中间件2(前) → 路由处理 → 中间件2(后) → 中间件1(后) → 响应 ``` --- ## 第八章:跨域 (ch08) ### 学习目标 学习如何配置 CORS(跨域资源共享)解决前后端分离开发中的跨域问题。 ### 核心知识点 1. **CORS 中间件配置** ```python from starlette.middleware.cors import CORSMiddleware app.add_middleware( CORSMiddleware, allow_origins=["*"], # 允许的源 allow_methods=["*"], # 允许的 HTTP 方法 allow_headers=["*"] # 允许的请求头 ) ``` 2. **配置参数说明** - `allow_origins` - 允许的源(域名),`["*"]` 表示允许所有 - `allow_credentials` - 是否允许携带凭证(Cookie) - `allow_methods` - 允许的 HTTP 方法 - `allow_headers` - 允许的请求头 ### 生产环境建议 ```python # 生产环境应该指定具体的域名 app.add_middleware( CORSMiddleware, allow_origins=["http://localhost:3000", "https://example.com"], allow_credentials=True, allow_methods=["GET", "POST", "PUT", "DELETE"], allow_headers=["*"] ) ``` ### 常见问题 - **开发环境**:可以使用 `allow_origins=["*"]` 方便开发 - **生产环境**:应该明确指定允许的域名,提高安全性 - **携带凭证**:如果前端需要发送 Cookie,需要设置 `allow_credentials=True` --- ## 第九章:FastAPI 案例 (ch09) ### 学习目标 综合运用前面所学知识,构建一个完整的用户管理 API 系统。 ### 项目结构 ``` ch09/ ├── main.py # 应用入口 ├── api/ │ └── user_api.py # 用户 API 接口 ├── dao/ │ └── user_dao.py # 数据访问层 ├── model/ │ └── models.py # 数据模型 └── common/ └── db_engine.py # 数据库引擎配置 ``` ### 核心知识点 1. **SQLModel 数据模型** ```python from sqlmodel import SQLModel, Field, Relationship class User(SQLModel, table=True): __tablename__ = "user" id: int = Field(primary_key=True) username: str = Field(max_length=20) password: str = Field(max_length=20) created_at: datetime ``` 2. **关系映射** - **一对一**:`Relationship(back_populates="user", sa_relationship_kwargs={"uselist": "false"})` - **一对多**:`Relationship(sa_relationship_kwargs={"uselist": "true"})` - **多对多**:`Relationship(link_model=UserRole, sa_relationship_kwargs={"uselist": "true"})` 3. **数据库连接** ```python from sqlmodel import create_engine URL = "mysql+pymysql://root:root@127.0.0.1:3306/sqlalchemy?charset=utf8" engine = create_engine( url=URL, echo=True, # 打印 SQL pool_size=20 # 连接池大小 ) ``` 4. **数据访问层(DAO)** ```python from sqlmodel import Session, select with Session(engine) as session: sql = select(User).where(User.id == id) user = session.exec(sql).one() ``` 5. **依赖注入(Depends)** ```python from fastapi import Depends def user_dao(): return UserDAO() @user.get("/id/{id}", response_model=User) async def get_user(id: int, user_dao: UserDAO = Depends(user_dao)): return await user_dao.get_user_by_id(id) ``` ### CRUD 操作 1. **添加(Create)** ```python with Session(engine) as session: session.add(user) session.commit() ``` 2. **查询(Read)** ```python # 根据 ID 查询 user = session.get(User, id) # 条件查询 sql = select(User).where(User.id == id) user = session.exec(sql).one() # 列表查询 sql = select(User) users = session.exec(sql).all() ``` 3. **更新(Update)** ```python with Session(engine) as session: sql = select(User).where(User.id == user.id) u = session.exec(sql).one() u.username = user.username session.commit() session.refresh(u) ``` 4. **删除(Delete)** ```python with Session(engine) as session: user = session.get(User, id) session.delete(user) session.commit() ``` ### 高级查询 1. **模糊查询** ```python sql = select(User).where(User.username.ilike(f"{name}%")) users = session.exec(sql).all() ``` 2. **统计查询** ```python from sqlalchemy import func sql = select(func.count(User.id)) count = session.exec(sql).one() ``` 3. **分页查询** ```python sql = select(User).offset(page_num).limit(page_size) users = session.exec(sql).all() ``` 4. **关联查询** ```python from sqlalchemy.orm import joinedload sql = select(User).options(joinedload(User.card)) \ .options(joinedload(User.addresses)) \ .where(User.id == id) user = session.exec(sql).unique().one() ``` --- ## 作业:商品信息的 CRUD (hw01) ### 作业要求 实现商品信息的完整 CRUD 操作,包括商品类型管理。 ### 项目结构 ``` hw01/ ├── main.py # 应用入口 ├── api/ │ ├── shop_api.py # 商品 API │ └── shop_type_api.py # 商品类型 API ├── dao/ │ └── shop_dao.py # 商品数据访问层 ├── model/ │ └── shop_model.py # 商品数据模型 ├── common/ │ └── db_engine.py # 数据库配置 └── static/ # 静态资源目录 ``` ### 数据模型 ```python class ShopType(SQLModel, table=True): """商品类型""" __tablename__ = 'shop_type' id: int = Field(primary_key=True) name: str = Field(max_length=20) shopInfos: List['ShopInfo'] = Relationship(back_populates="shop_type") class ShopInfo(SQLModel, table=True): """商品信息""" __tablename__ = "shop_info" id: int = Field(primary_key=True) name: str = Field(max_length=20) type_id: int = Field(foreign_key="shop_type.id") price: float stock: int shop_type: 'ShopType' = Relationship(back_populates="shopInfos") ``` ### 实现功能 1. **商品查询** - 根据 ID 查询商品 - 根据名称模糊查询商品 - 查询所有商品列表 2. **商品管理** - 添加商品 - 修改商品 - 删除商品 3. **商品类型管理** - 商品类型的 CRUD 操作 ### 技术要点 - 使用 SQLModel 进行 ORM 映射 - 实现一对多关系(商品类型 → 商品) - 使用依赖注入管理 DAO 对象 - 使用响应模型控制返回数据 - 集成静态资源服务 --- ## 总结 ### 学习路径 1. **基础入门**:了解 FastAPI 基本使用 2. **静态资源**:学习静态文件服务 3. **HTTP 方法**:掌握不同请求方式 4. **路由管理**:实现模块化开发 5. **参数处理**:学习各种参数接收方式 6. **响应控制**:掌握响应数据格式化 7. **中间件**:实现请求拦截和处理 8. **跨域配置**:解决前后端分离问题 9. **综合案例**:构建完整 API 系统 ### 核心技术栈 - **FastAPI** - 现代、快速的 Web 框架 - **SQLModel** - 基于 SQLAlchemy 的 ORM 框架 - **Pydantic** - 数据验证和序列化 - **Uvicorn** - ASGI 服务器 - **MySQL** - 关系型数据库 ### 最佳实践 1. **项目结构**:采用分层架构(API → DAO → Model) 2. **依赖注入**:使用 `Depends` 管理依赖关系 3. **数据验证**:使用 Pydantic 进行数据验证 4. **响应模型**:使用 VO 对象控制返回数据 5. **错误处理**:统一异常处理机制 6. **文档完善**:使用装饰器参数完善 API 文档 ### 扩展学习 - 用户认证和授权(JWT) - 文件上传和下载 - WebSocket 实时通信 - 异步任务处理(Celery) - API 版本控制 - 单元测试和集成测试 - 性能优化和缓存 - 部署和 DevOps --- ## 附录 ### 常用命令 ```bash # 安装依赖 pip install -r requirements.txt # 启动服务 python main.py # 或使用 uvicorn uvicorn main:app --host 127.0.0.1 --port 8000 --reload ``` ### 常用 URL - API 文档(Swagger UI):`http://127.0.0.1:8000/docs` - 替代文档(ReDoc):`http://127.0.0.1:8000/redoc` - OpenAPI JSON:`http://127.0.0.1:8000/openapi.json` ### 参考资源 - [FastAPI 官方文档](https://fastapi.tiangolo.com/) - [SQLModel 文档](https://sqlmodel.tiangolo.com/) - [Pydantic 文档](https://docs.pydantic.dev/) - [SQLAlchemy 文档](https://docs.sqlalchemy.org/) --- *笔记生成时间:2024年* *项目路径:D:\System\Desktop\SPS\fasyapi-study*