fastapi教程翻译(四):Request Body(请求体)
一、什么是请求体?
当您需要将数据从客户端(例如浏览器)发送到API时,可以将其作为 “请求体” 发送。
请求体是客户端发送到您的API的数据。 响应体是您的API发送给客户端的数据。
API几乎总是必须发送一个响应体,但是客户端并不需要一直发送请求体。
定义请求体,需要使用 Pydantic 模型。
- 不能通过
GET
请求发送请求体- 发送请求体数据,必须使用以下几种方法之一:
POST
(最常见),PUT
DELETE
PATCH
.
二、导入Pydantic's
的 BaseModel
定义模型
- 你需要从
pydantic
中导入BaseModel
- 你需要从
import BaseModel from pydantic
三、创建数据模型
- 然后,声明你的数据模型为一个类,且该类继承
BaseModel
.
所有的属性都用标准Python类
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str = None
price: float tax: float = None
和Query参数一样:数据类型的属性如果不是必须的话,可以拥有一个默认值。否则,该属性就是必须的。
- 可以使用
None
让这个属性变为可选的。
例如,上面的模型Item
声明了一个JSON
对象(或Pythondict
),例如:
{
"name": "Foo",
"description": "An optional description",
"price": 45.2,
"tax": 3.5
}
...description
和tax
属性是可选的(因为有默认值None
),所以下面这个JSON
对象也是有效的:
{
"name": "Foo",
"price": 45.2
}
四、将模型定义为参数
将上面定义的模型添加到你的路径操作中,就和定义Path和Query参数一样的方式:
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
...声明参数的类型为你创建的模型 Item
.
五、使用 Request Body
的好处
通过那样定义Python 类型为pydantic
的model
,FastAPI 将会:
- 将读取请求的正文读取为JSON类型。
- 转换相应的类型(如果需要)。
- 验证数据。
如果数据无效,它将返回一个清晰的错误,指出错误数据的确切位置和来源.
- 在参数
item
中为您提供接收的数据。
当您在函数中将其声明为
Item
类型时,您还将获得Item
所有属性及其类型的所有编辑器支持(自动补全等)。
*为您的模型生成 JSON Schema 定义,如果对您的项目有意义,您还可以在其他任何喜欢的地方使用它们。
- 这些
Schemas
将是生成的OpenAPI Schema
的一部分,并由自动文档UI使用
六、自动文档
模型的 JSON Schema
将成为OpenAPI生成模式的一部分,并将显示在交互式API文档中:
并且还将在需要它们的每个路径操作的API文档中使用:
七、编辑器支持
在你的编辑器中,编写的函数中,你将会获得类型提示和补全:
注意:
如果你接收的是一个dict
,而不是一个Pydantic model
将不会获得提示和补全。
您也会获得类型操作错误检查:
这并非偶然,整个框架都是围绕该设计构建的。
并且在进行任何完善之前,都要在设计阶段进行全面测试,以确保它可以与所有编辑器一起使用。
Pydantic
本身甚至进行了一些更改以支持此操作。
之前的屏幕截图是使用Visual Studio Code 拍摄的。
但是您可以通过PyCharm 和大多数其他Python编辑器获得相同的编辑器支持:
八、使用这个模型
在函数内部,您可以直接访问模型对象的所有属性:
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
item_dict = item.dict()
if item.tax:
price_with_tax = item.price + item.tax item_dict.update({"price_with_tax": price_with_tax})
return item_dict
九、Request body + path 参数
你可以同时定义Path参数
和请求体参数
.
FastAPI 将:
- 识别出与路径参数相匹配的功能参数应从路径中获取
- 声明为Pydantic模型的功能参数应从请求主体中获取。
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
app = FastAPI()
@app.put("/items/{item_id}")
async def create_item(
item_id: int,
item: Item
):
return {"item_id": item_id, **item.dict()}
十、Request body + path + query 参数
你可以同时定义Path参数
、Query参数
和 请求体参数
.
** FastAPI **将识别它们中的每一个并从正确的位置获取数据。
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
app = FastAPI()
@app.put("/items/{item_id}")
async def create_item(
item_id: int,
item: Item,
q: str = None
):
result = {"item_id": item_id, **item.dict()}
if q:
result.update({"q": q})
return result
FastAPI识别过程:
- 如果在 path中也声明了该参数,它将用作path参数。
- 如果参数是 单一类型(例如int,float,str,str,bool等),它将被解释为 query参数。
如果参数声明为Pydantic模型*的类型,则它将被解释为 请求体。