7天掌握FastAPI-参数
1.6.1分析
同一段接口逻辑,根据参数不同返回不同的数据
1.6.2介绍
参数就是客户端发送请求时附带的额外信息和指令
参数的作用是让同一个接口能根据不同的输入,返回不同的输出,实现动态交互
1.6.3参数分类
1.6.3.1路径参数(Path Parameter)
- 位置:URL 路径的一部分,格式为 /资源/{参数名}(如 /book/{id})。
- 作用:指向唯一的、特定的资源(如获取某本具体书籍的信息)。
- 常用方法:GET(用于获取资源)。
@app.get("/book/{id}") # 定义请求的的路径,请求方式为get async def get_book(id: int): # 定义这个接口,接收一个参数id,数据类型为int # 返回响应结果 return {"id": id, "title": f"这是第{id}本书"}--->运行后查看旁边的运行结果
接口文档中进行测试
注意:这里进行参数调试的时候,必须填一个值,否则直接excute会报错
1.6.3.1.1类型注解Path
FastAPI 允许为参数声明额外的信息和校验
@app.get("/book/{id}") async def get_book(id: int): return {"id": id, "title": f"这是第{id}本书"}1.6.3.1.2导入 FastAPI 的 Path 函数
@app.get("/book/{id}") async def get_book(id: int = Path()): return {"id": id, "title": f"这是第{id}本书"}# 定义请求的的路径,请求方式为get @app.get("/book/{id}") # 定义这个接口,接收一个参数id,数据类型为int async def get_book(id: int=Path(...,gt=0,lt=101)): # 返回响应结果 return {"id": id, "title": f"这是第{id}本书"}重启,然后找到接口填写111
1.6.3.1.3会发现报错了,id要求不能大于101,
# 定义请求的的路径,请求方式为get @app.get("/book/{id}") # 定义这个接口,接收一个参数id,数据类型为int async def get_book(id: int=Path(...,gt=0,lt=101,description="书籍id,取值范围为1-100")): # 返回响应结果 return {"id": id, "title": f"这是第{id}本书"}# 需求:查找书籍的作者,路径参数 name,长度范围 2-10 @app.get("/book/{name}") async def get_name(name: str = Path(..., min_length=2, max_length=10, description="书籍名称,长度范围为2-10")): return {"msg": f'这是{name}的信息'}1.6.3.1.4小结
- 路径参数出现在什么位置?
URL 路径的一部分
- 如何为路径参数添加类型注解?
Python 原生注解 和 Path 注解
1.6.3.1.5练习
需求:定义两个接口,携带路径参数,并使用 Path 来实现类型注解
具体如下:
- 接口1:以 新闻分类 id 为参数设计 URL,id 范围为 1 ~ 100
- 接口2:以 新闻分类名称为参数设计 URL,分类名称长度为 2 ~ 10
from fastapi import FastAPI, Path app = FastAPI() # --------------------------------------------------------- # 接口1:新闻分类 ID # 需求:id 范围为 1 ~ 100 # URL 示例: /news/category/50 # --------------------------------------------------------- @app.get("/news/category/{category_id}") async def get_news_by_id( category_id: int = Path( ..., title="新闻分类ID", description="新闻分类的唯一标识符", ge=1, # 大于等于 1 le=100 # 小于等于 100 ) ): return {"category_id": category_id, "message": "成功获取该分类下的新闻"} # --------------------------------------------------------- # 接口2:新闻分类名称 # 需求:分类名称长度为 2 ~ 10 # URL 示例: /news/search/科技 # --------------------------------------------------------- @app.get("/news/search/{category_name}") async def get_news_by_name( category_name: str = Path( ..., title="新闻分类名称", description="新闻分类的名称关键字", min_length=2, # 最小长度 2 max_length=10 # 最大长度 10 ) ): return {"category_name": category_name, "message": "成功搜索该分类相关的新闻"}1.6.3.2查询参数(Query Parameter)
- 位置:URL 中 ? 之后,格式为 key1=value1&key2=value2(如 ?page=1&sort=desc)。
- 作用:对资源集合进行过滤、排序、分页等操作(如查询“第1页、按时间降序”的书籍列表)。
- 常用方法:GET(用于获取资源集合的筛选结果)。
声明的参数不是路径参数时,路径操作函数会把该参数自动解释为查询参数
在news_list后面拼接参数,如右图:
# 需求:查询新闻页->分页,skip:跳过的记录数,limit:返回的记录数 10 @app.get("/news/news_list") async def get_news_list(skip: int, limit: int = 10): return {"skip": skip, "limit": limit}1.6.3.2.1类型注解 Query
导入 FastAPI 的 Query 函数
# 需求:查询新闻页->分页,skip:跳过的记录数,limit:返回的记录数 10 @app.get("/news/news_list") async def get_news_list( skip: int = Query(0, description="跳过的记录数",lt=100), limit: int = Query(10, description="返回的记录数",lt=100) ): return {"skip": skip, "limit": limit}1.6.3.2.2小结
- 查询参数出现在什么位置?
URL? 之后, k1=v1&k2=v2
- 如何为查询参数添加类型注解?
Python 原生注解 和 Query 注解
1.6.3.2.3练习
需求:设计接口查询图书,要求携带两个查询参数:图书分类和价格
参数具体要求:
- 图书分类:默认值为 Python开发,长度限制5 ~ 255
- 价格:限制大小范围 50 ~ 100
from fastapi import FastAPI, Query app = FastAPI() @app.get("/books/") async def read_books( # 需求:图书分类,默认值为 "Python开发",长度限制 5 ~ 255 category: str = Query( "Python开发", min_length=5, max_length=255, description="图书的分类名称" ), # 需求:价格,限制大小范围 50 ~ 100 price: float = Query( ..., ge=50, le=100, description="图书的价格范围" ) ): return { "category": category, "price": price, "message": "查询成功" }1.6.3.3请求体(Request Body)
- 位置:HTTP 请求的消息体(body)中,常以 JSON 等格式携带数据。
- 作用:用于创建、更新资源,或携带大量数据(如提交书籍的详细信息、更新用户资料)。
- 常用方法:POST(创建资源)、PUT(更新资源)等。
在HTTP协议中,一个完整的请求由三部分组成:
① 请求行:包含方法、URL、协议版本
② 请求头:元数据信息(Content-Type、Authorization等)
③ 请求体:实际要发送的数据内容
1.6.3.3.1定义类型
from pydantic import BaseModel class User(BaseModel): username: str password: str- 类型注解
@app.post("/register") async def register(user: User): return user响应结果如下:
1.6.3.3.2练习
需求:设计接口新增图书,图书信息包含:书名、作者、出版社、售价
from fastapi import FastAPI from pydantic import BaseModel from typing import Optional app = FastAPI() # 1. 定义数据模型 (Pydantic Model) class BookItem(BaseModel): title: str # 书名 author: str # 作者 publisher: str # 出版社 price: float # 售价 # 2. 定义新增图书接口 @app.post("/books/", summary="新增图书") async def create_book(book: BookItem): """ 接收 JSON 格式的图书信息并返回 """ # 这里通常会写数据库插入逻辑 return { "message": "图书新增成功", "book_info": book }1.6.3.3.3类型注解 Field
导入 pydantic 的Field函数
from pydantic import BaseModel, Field class User(BaseModel): username: str = Field(...) password: str = Field(...)# 注册:用户名和密码->str class User(BaseModel): username: str = Field(default="张三", min_length=2, max_length=10, description="用户名,长度范围为2-10") password: str = Field(min_length=6, max_length=20, description="密码,长度范围为6-20") @app.post("/register") async def register(user: User): return user1.6.3.3.4小结
- 请求体参数的作用是什么?
创建、更新资源
- 如何定义、使用请求体参数?
# 注册:用户名和密码->str class User(BaseModel): username: str = Field(default="张三", min_length=2, max_length=10, description="用户名,长度范围为2-10") password: str = Field(min_length=6, max_length=20, description="密码,长度范围为6-20") @app.post("/register") async def register(user: User): return user- 如何为请求体参数添加类型注解?
Python 原生注解 和 Field 注解
1.6.3.3.5练习
需求:设计接口新增图书,图书信息包含:书名、作者、出版社、售价
具体要求如下:
书名:不能为空;长度 2 ~ 20
作者:长度 2 ~ 10
出版社:默认值“黑马出版社”
售价:不能为空;价格大于0元
from fastapi import FastAPI from pydantic import BaseModel, Field from typing import Optional app = FastAPI() # 1. 定义数据模型 class Book(BaseModel): # 书名:不能为空;长度 2 ~ 20 book_name: str = Field( ..., min_length=2, max_length=20, description="书名,必填,2-20字" ) # 作者:长度 2 ~ 10 author: str = Field( ..., min_length=2, max_length=10, description="作者,必填,2-10字" ) # 出版社:默认值“黑马出版社” publisher: str = Field( default="黑马出版社", description="出版社,默认黑马出版社" ) # 售价:不能为空;价格大于0元 price: float = Field( ..., gt=0, description="价格,必填,大于0" ) # 2. 定义新增图书接口 @app.post("/books", summary="新增图书") async def create_book(book: Book): """ 接收图书信息,校验通过后返回 """ # 这里可以添加保存到数据库的逻辑 return {"message": "图书新增成功", "book_data": book}1.6.3.3.4核心区别总结
完整代码
from fastapi import FastAPI, Path, Query from pydantic import BaseModel,Field # 创建FastAPI实例 app = FastAPI() @app.get("/") async def root(): return {"message": "Hello World 666"} @app.get("/hello/{name}") async def say_hello(name: str): return {"message": f"Hello {name}"} # 访问/hello响应结果 msg:你好 FastAPI @app.get("/hello") async def get_hello(): return {"msg": "你好 FastAPI"} @app.get(" /user/hello") async def get_user_hello(): return {"msg": "我正在学习 FastAPI ......"} # 定义请求的的路径,请求方式为get @app.get("/book/{id}") # 定义这个接口,接收一个参数id,数据类型为int async def get_book(id: int = Path(..., gt=0, lt=101, description="书籍id,取值范围为1-100")): # 返回响应结果 return {"id": id, "title": f"这是第{id}本书"} # 需求:查找书籍的作者,路径参数 name,长度范围 2-10 @app.get("/book/{name}") async def get_name(name: str = Path(..., min_length=2, max_length=10, description="书籍名称,长度范围为2-10")): return {"msg": f'这是{name}的信息'} # 需求:查询新闻页->分页,skip:跳过的记录数,limit:返回的记录数 10 @app.get("/news/news_list") async def get_news_list( skip: int = Query(0, description="跳过的记录数",lt=100), limit: int = Query(10, description="返回的记录数",lt=100) ): return {"skip": skip, "limit": limit} # 注册:用户名和密码->str class User(BaseModel): username: str = Field(default="张三", min_length=2, max_length=10, description="用户名,长度范围为2-10") password: str = Field(min_length=6, max_length=20, description="密码,长度范围为6-20") @app.post("/register") async def register(user: User): return user