fastapi之模型嵌套

343 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情

  • 在fastapi中,请求体的数据结构支持任意类型的嵌套。

列表和集合

  • 请求体中的一个字段的值可以是包好多个元素的列表,且支持定义元素的类型。
  • 请求体中的一个字段的值也可以是包含多个元素的集合,此时该字段的值具有了自动去重的功能。
 from typing import Union, List, Set
 ​
 from fastapi import FastAPI
 from pydantic import BaseModel
 ​
 app = FastAPI()
 ​
 ​
 class Item(BaseModel):
     name: str
     description: Union[str, None] = None
     price: float
     tax: Union[float, None] = None
     tags: List[str] = []        # tags: Set[str] = set()
 ​
 ​
 @app.put("/items/{item_id}")
 def update_item(item_id: int, item: Item):
     results = {"item_id": item_id, "item": item}
     return results

模型嵌套

  • 请求体中的一个字段的值可以是另一个Pydantic模型对象
  • 此时被嵌套的模型的字段也会有类型提示,数据校验等。
 from typing import Set, Union
 ​
 from fastapi import FastAPI
 from pydantic import BaseModel
 ​
 app = FastAPI()
 ​
 ​
 class Image(BaseModel):
     url: str
     name: str
 ​
 ​
 class Item(BaseModel):
     name: str
     description: Union[str, None] = None
     price: float
     tax: Union[float, None] = None
     tags: Set[str] = set()
     image: Union[Image, None] = None
 ​
 ​
 @app.put("/items/{item_id}")
 def update_item(item_id: int, item: Item):
     results = {"item_id": item_id, "item": item}
     return results
  • 此时预期的请求体数据格式如下:
 {
     "name": "Foo",
     "description": "The pretender",
     "price": 42.0,
     "tax": 3.2,
     "tags": ["rock", "metal", "bar"],
     "image": {
         "url": "http://example.com/baz.jpg",
         "name": "The Foo live"
     }
 }
  • 除此之外,被嵌套的模型元素也可以是列表元素
 class Image(BaseModel):
     url: str
     name: str
 ​
 ​
 class Item(BaseModel):
     name: str
     description: Union[str, None] = None
     price: float
     tax: Union[float, None] = None
     tags: Set[str] = set()
     images: Union[List[Image], None] = None
  • 此时需要的请求体数据格式:
 {
     "name": "Foo",
     "description": "The pretender",
     "price": 42.0,
     "tax": 3.2,
     "tags": [
         "rock",
         "metal",
         "bar"
     ],
     "images": [
         {
             "url": "http://example.com/baz.jpg",
             "name": "The Foo live"
         },
         {
             "url": "http://example.com/dave.jpg",
             "name": "The Baz"
         }
     ]
 }

请求体是列表结构

  • 请求体的数据除了是字典形式,可以是列表形式
 from typing import List
 ​
 from fastapi import FastAPI
 from pydantic import BaseModel
 ​
 app = FastAPI()
 ​
 ​
 class Image(BaseModel):
     url: str
     name: str
 ​
 ​
 @app.post("/images/multiple/")
 def create_multiple_images(images: List[Image]):
     return images
 ​

请求体是字典结构

  • 当我们不知道请求体字段的键和值的时候,可以参考如下代码
  • 虽然JSON只支持str做键,但是因为fastapi有数据转换,所有请求体字段中的key是可以定义为int
 from typing import Dict
 ​
 from fastapi import FastAPI
 ​
 app = FastAPI()
 ​
 ​
 @app.post("/index-weights/")
 def create_index_weights(weights: Dict[int, float]):
     return weights