fastapi请求体参数之Body

239 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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的基本使用

  • PathQuery类似,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}