持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情
多个请求体参数
- 当客户端传过来的请求体参数有多个时,如:
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
},
"user": {
"username": "dave",
"full_name": "Dave Grohl"
}
}
- 此时需要定义2个数据模型,一个是
Item一个是User(两个 Pydantic 模型参数) - FastAPI 将自动对请求中的数据进行转换,因此
item参数将接收指定的内容,user参数也是如此。 - 此时也有数据的校验,并且像现在这样为 OpenAPI 模式和自动化文档对其进行记录。
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
class User(BaseModel):
username: str
full_name: Optional[str] = None
@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item, user: User):
results = {"item_id": item_id, "item": item, "user": user}
return results
补充:一般更新数据时使用PUT请求
请求体中的单一值
- 如果请求体中存在一个单一键值对,比如下面的
importance,那fastapi中该如何获取该参数呢?
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
},
"user": {
"username": "dave",
"full_name": "Dave Grohl"
},
"importance": 5
}
- 此时因为
importance不像item那样对应一个字典,所以需要特殊处理,使用Body
from typing import Union
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
class User(BaseModel):
username: str
full_name: Union[str, None] = None
@app.put("/items/{item_id}")
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
Body的基本使用
- 和
Path或Query类似,Body是用来专门处理请求参数的,同样的,它有转换数据类型,校验,生成文档等。
from fastapi import Body, FastAPI
app = FastAPI()
@app.post("/items/{item_id}")
def update_item(item_id: int, importance: int = Body(default=10, ge=5)):
results = {"item_id": item_id, "importance": importance}
return results
嵌入单个请求体参数
- 如果客户端传给服务端的请求体参数格式变了,那后端代码该如何正确获取请求体参数呢?
# 原先的
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
# 现在的
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
}
- 非常简单,只要在
Body中设置embed=True
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
return {"item_id": item_id, "item": item}