
一、查询参数Query Parameters查询参数是URL中?后面的键值对组合格式为key1value1key2value2用于对资源进行「筛选、分页、排序」等辅助操作。例如/items?skip0limit10skip跳过条数、limit查询条数是查询参数/users?name张三age20name姓名、age年龄是查询参数核心特点可选性默认可省略可设置默认值辅助性不用于标识唯一资源仅用于过滤、分页等灵活性支持单个键对应多个值如/items?tagsfruittagscheap为什么需要Query类型注解基础的查询参数写法如skip: int 0只能实现「类型校验默认值」但实际开发中需要更精细的控制分页参数limit必须≥1且≤50范围校验搜索关键词q长度必须≤100长度限制筛选标签tags支持多个值传入多值参数接口文档需要显示查询参数的详细描述元数据配置Query类型注解正是为解决这些问题而生它是FastAPI提供的「查询参数高级配置工具」与Path注解同源均基于Pydantic功能互补。查询参数 vs 路径参数核心区别什么是Query类型注解Query是FastAPI从fastapi模块导出的专用类用于对查询参数进行「精细化配置」功能与Path注解一致仅适用场景不同。核心特点兼容Python原生类型注解支持更丰富的校验规则配置自动同步到/docs接口文档提升可读性基于Pydantic实现校验失败返回标准化422错误支持多值参数、正则匹配等高级特性Query注解最简示例python# Query类型注解基础示例 fromfastapiimportFastAPI,Queryimportuvicorn appFastAPI(titleQuery注解教程,version1.0.0)# Query注解限制limit≥1且≤50添加详细描述app.get(/items/advanced/,summaryQuery注解基础示例)defread_items_advanced(# 核心语法参数名: 类型 Query(默认值, 校验规则/元数据)skip:intQuery(0,ge0,description跳过条数不能为负数),limit:intQuery(10,ge1,le50,description查询条数1-50条)): Query注解分页接口 :param skip: 跳过条数≥0 :param limit: 查询条数1-50 :return: 分页结果 fake_items[{item_id:i,name:f物品{i}}foriinrange(skip,skiplimit)]return{code:200,skip:skip,limit:limit,data:fake_items}if__name____main__:uvicorn.run(main:app,host127.0.0.1,port8000,reloadTrue)### 核心校验规则参数  # 二、请求体与 Pydantic 模型 请求体解决的问题 1.- 路径参数只能传递简单值ID、名称且长度有限 2.- 查询参数适合传递少量辅助数据传递复杂数据如用户注册信息、商品详情时 URL 会冗长、不安全 优势 数据容量大、格式灵活支持 JSON / 表单 / 文件、传输安全配合 HTTPS #### 三个核心参数类型的适用场景对比  ## 请求体通常与「非查询类」HTTP 方法配合使用符合 RESTful 规范 POST创建资源如用户注册、新增商品→ 必用请求体 - PUT全量更新资源如修改商品所有信息→ 必用请求体 - PATCH部分更新资源如修改商品价格→ 常用请求体 - GET查询资源 → 禁止使用请求体不符合 HTTP 规范 ## 带字段校验的请求体模型 python python # Pydantic字段校验示例 from fastapi import FastAPI from pydantic import BaseModel, Field import uvicorn app FastAPI(title请求体字段校验教程, version1.0.0) # 带字段校验的用户注册模型 class UserCreateWithValidate(BaseModel): 带字段校验的用户注册请求体模型 # 用户名3-20位仅字母/数字/下划线必填 username: str Field( ..., # 必填字段 min_length3, max_length20, patternr^[a-zA-Z0-9_]$, title用户名, description3-20位仅支持字母、数字、下划线, examplezhangsan_123 ) # 邮箱符合邮箱格式必填 email: str Field( ..., patternr^[a-zA-Z0-9._%-][a-zA-Z0-9.-]\.[a-zA-Z]{2,}$, title邮箱, description请输入合法的邮箱地址, examplezstest.com ) # 密码6-20位必填 password: str Field( ..., min_length6, max_length20, title密码, description6-20位字符建议包含字母和数字, example123456a ) # 年龄1-120岁可选默认None age: int | None Field( None, ge1, le120, title年龄, description1-120岁之间, example25 ) # 带校验的注册接口 app.post(/users/register/validate/, summary带字段校验的注册接口) def user_register_validate(user_info: UserCreateWithValidate): return { code: 200, message: 注册成功带字段校验, data: { username: user_info.username, email: user_info.email, age: user_info.age or 未填写 } } if __name__ __main__: uvicorn.run(main:app, host127.0.0.1, port8000, reloadTrue)# 三、什么是 ORM为什么要用 Tortoise-ORM ORM 全称是 Object-Relational Mapping对象关系映射 。它的核心思想是用 Python 类来代表数据库中的表用类的实例来代表表中的一行记录。 没有 ORM 时你需要手写 SQL 语句来操作数据库。 ## ORM 的优势 - 面向对象用 Python 代码替代 SQL 语句更符合编程思维。 - 安全性自动进行参数化查询防止 SQL 注入攻击。 - 跨数据库同一套代码可以无缝切换 SQLite、PostgreSQL、MySQL 等数据库。 - 关系管理自动处理表与表之间的外键、多对多等关系。 - 可维护性表结构集中定义在模型类中修改和管理更方便。 ### 为什么选择 Tortoise-ORM 在 Python 异步 Web 开发中传统的 ORM如 SQLAlchemy 1.x 的同步模式在执行数据库查询时会阻塞整个线程这与 FastAPI 的异步非阻塞理念背道而驰通常使用Tortoise-ORM或者SQLAlchemy 2.0。 ### 同步 ORM vs 异步 ORM 对比  ## 环境搭建与 FastAPI 集成 python pip install tortoise-orm #MySQL 异步驱动推荐 asyncmy pip install asyncmy 或者 pip install aiomysql # 安装 Aerich 迁移工具后面会用到 pip install aerich # 安装 FastAPI 和 Uvicorn pip install fastapi uvicorn[standard]项目结构规划数据库配置文件配置中最重要的就是这一部分。关系字段的 on_delete 策略详解在定义 ForeignKeyField 或 OneToOneField 时必须指定 on_delete 参数它定义了当父表记录被删除时子表关联记录的行为。这是保证数据一致性的重要一环单表查询先定义User模型 app/models/user.py再导出user模型app/models/init.py然后Aerich 数据库迁移最后查询数据app/routers/user.py示例fromdatetimeimportdatetime,date,timedeltafromfastapiimportAPIRouter,Queryfromtortoise.expressionsimportQfromapp.modelsimportTaskfromapp.schemas.day01importTaskCreateRequest task_routerAPIRouter(prefix/task,tags[任务管理],)task_router.get(/all,summary获取所有任务,description获取所有任务)asyncdefgetAllTask(status:int|NoneQuery(None,description0待办 1进行中 2已完成 3已取消不传查全部),keyword:strQuery(,description任务标题模糊搜索关键词),sort_priority:boolQuery(False,descriptionTrue按优先级紧急→高→中→低排序False默认创建时间倒序)):queryQ()ifstatusisnotNone:queryQ(statusstatus)ifkeyword.strip():queryQ(title__icontainskeyword.strip())task_queryTask.filter(query)# 3. 优先级排序紧急(3)→高(2)→中(1)→低(0)降序ifsort_priority:task_querytask_query.order_by(-priority)else:# 默认按创建时间倒序task_querytask_query.order_by(-created_at)tasksawaittask_query.all()# 通过任务状态查询tasks_list[]fortaskintasks:tasks_list.append({id:task.id,title:task.title,status:task.status,priority:task.priority,due_date:task.due_date,created_at:task.created_at,})return{code:1,message:success,data:tasks_list}注意一定要在在man.py中注册子路由注释上面示例写了查全部以及条件查询和排序并在其中查询时做判断没传就为空或者为设置的默认值传了直接查询。单表增加和查询过程一样导包和名称不再展示示例task_router.post(/save,summary保存任务,description保存任务)asyncdefsave_task(task:TaskCreateRequest):task1awaitTask.create(user_idtask.user_id,titletask.title,descriptiontask.description,statustask.status,prioritytask.priority,due_datetask.due_date)return{code:1,message:保存成功,data:task1}其中所要添加的字段我已在schemas中验证会在最后展示它全部的代码单表修改示例task_router.put(/update/{id},summary修改数据,description修改数据)asyncdefupdate_task(id:int,task:TaskCreateRequest):task1awaitTask.get_or_none(idid)iftask1isNone:return{code:0,message:任务不存在}task_dicttask.dict(exclude_unsetTrue)awaitTask.filter(idid).update(**task_dict)return{code:1,message:修改成功}单表删除示例;task_router.delete(/delete/{id},summary删除任务,description删除任务)asyncdefdelete_task(id:int):task1awaitTask.get_or_none(idid)iftask1isNone:return{code:0,message:任务不存在}awaitTask.filter(idid).delete()return{code:1,message:删除成功}schemas的代码frompydanticimportBaseModel,FieldclassTaskCreateRequest(BaseModel):user_id:intField(...,title用户ID,description用户ID,example1)title:strField(...,title任务标题,min_length1,max_length100,description任务标题,example学习FastAPI)description:strField(None,title任务描述,min_length1,max_length1000,description任务描述,example学习FastAPI)status:intField(0,title任务状态,description任务状态,example0)priority:intField(1,title任务优先级,description任务优先级,example1)#截止时间不能早于当前时间due_date:strField(None,title任务截止时间,description任务截止时间,example2026-07-20 00:00:00)classTaskUpdateRequest(BaseModel):title:strField(None,title任务标题,min_length1,max_length100,description任务标题,example学习FastAPI)description:strField(None,title任务描述,min_length1,max_length1000,description任务描述,example学习FastAPI)status:intField(None,title任务状态,description任务状态,example0)priority:intField(None,title任务优先级,description任务优先级,example1)due_date:strField(None,title任务截止时间,description任务截止时间,example2026-07-20 00:00:00)completed_at:strField(None,title任务完成时间,description任务完成时间,example2026-07-20 00:00:00)今天主要掌握这些