fastapi教程翻译(七):Body - 多种参数
现在我们已经了解了如何使用路径Path
和查询Query
,让我们来看一下请求主体Body
声明的更高级用法。
一、混合使用Path
, Query
和 请求体参数
首先,当然,您可以自由地混合使用Path
,Query
和请求主体参数声明,FastAPI
将知道该怎么做。
1. 编写一个api
可以通过将默认值设置为None
来声明主体参数为可选:
from fastapi import FastAPI, Path
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
@app.put("/items/{item_id}")
async def update_item(
*,
item_id: int = Path(..., title="The ID of the item to get", ge=0, le=1000),
q: str = None,
item: Item = None,
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
if item:
results.update({"item": item})
return results
上述请求体参数的正确格式如下:
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
2. postman测试
2.1 case1: 传入参数格式1:
2.2 case2: 传入参数格式2:
- 参数如下
{"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}}
通过Postman测试如下:
发现报错422,请求语法错误,请求的参数不对,说明这种请求参数格式不对。
注意: 在这种情况下,将从请求体中提取的item
是可选的。 由于它具有None
默认值。
二、多个模型的请求体参数
1. 定义多个 Body
参数,
例如: item
和 user
均为Pydantic
模型
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
class User(BaseModel):
username: str
full_name: str = None
@app.put("/items/{item_id}")
async def update_item(*, item_id: int, item: Item, user: User):
results = {"item_id": item_id, "item": item, "user": user}
return results
在这种情况下,它将使用参数名称作为正文中的key
,Pydantic
的类作为key
的内容
上述请求体参数的正确格式如下:
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
},
"user": {
"username": "dave",
"full_name": "Dave Grohl"
}
}
2. postman测试
2.1 case1: 传入参数格式1
2.2 case2:传入参数格式2
注意: 即使item
已经和以前一样的被定义,它仍然期望被放在请求体中,使用item
关键字标记.
- FastAPI将根据请求执行自动转换,以便参数项接收其特定内容,并且与用户相同。
- 它将执行复合数据的验证,并将像OpenAPI模式和自动文档一样对其进行记录。
三、使用Body
定义单值的请求体参数
1. Body
方法
Query
和Path
方法定义了额外的数据为查询和路径参数,FastAPI也为请求体定义了Body
方法。
例如,扩展之前的模型,之前的模型还需要额外增加一个参数:除去item
和user
这两个字段之外,还需要importance
在请求体中
如果你直接定义它,因为他是一个单值,FastAPI会默认将其定义为
query
参数。
但是你可以使用Body
参数,让FastAPI将其视为请求体的key:
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
class User(BaseModel):
username: str
full_name: str = None
@app.put("/items/{item_id}")
async def update_item(
*, item_id: int, item: Item, user: User, importance: int = Body(...)
):
results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
return results
在这个例子中,FastAPI的预期的请求体如下:
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
},
"user": {
"username": "dave",
"full_name": "Dave Grohl"
},
"importance": 5
}
2. postman测试
- 同样的,它会转化数据类型,数据验证以及文档等等。
四、多个body
和query
参数
当然,除了请求体参数外,您还可以在需要时声明其他查询参数。
默认,单个参数会被解析为查询参数,你不必用添加Query
方法,你只需要
q: str = None
就如:
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
class User(BaseModel):
username: str
full_name: str = None
@app.put("/items/{item_id}")
async def update_item(
*,
item_id: int,
item: Item,
user: User,
importance: int = Body(..., gt=0),
q: str = None
):
results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
if q:
results.update({"q": q})
return results
说明: 请求体
Body
方法也有如Query
、Path
的数据验证和元数据参数的参数,稍后你将看见。
五、嵌入单个请求体参数
假设您只有Pydantic
模型Item
中的单个body
参数。
默认情况下,FastAPI将直接希望得到body
参数。
但是,如果您想得到一个带有key的JSON,并且在key对应的包含模型内容,就像声明额外的主体参数时那样,则可以使用嵌入的特殊Body参数:
item: Item = Body(..., embed=True)
如下:
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
@app.put("/items/{item_id}")
async def update_item(*, item_id: int, item: Item = Body(..., embed=True)):
results = {"item_id": item_id, "item": item}
return results
在这个例子中,FastAPI预期的请求体数据格式如下:
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
}
而不是(参考文章的第一部分,如果不使用embed
方法,则默认的传递方式如下):
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
说明:单个
Body
参数的时候,可以使用embed
参数。
六、总结
- 即使请求只能有一个请求体,也可以将多个
body
参数添加到路径操作函数中。 - 但是FastAPI会处理它,为您的函数提供正确的数据,并在路径操作中验证并记录正确的模式。
- 您还可以声明将单数作为主体的一部分接收。
- 而且,即使仅声明了一个参数,您也可以指示FastAPI将主体嵌入键中。