FastAPI(14)- 路径操作函数参数的类型是一个嵌套 Pydantic Model 的使用场景

带有类型参数的字段

Python 有一种特定的方法来声明具有内部类型或类型参数的列表

其实前面都见过,就是

List[str]
Set[str]
Tuple[str]
Dict[str, int]

 

在 Pydantic Model 中使用 typing 提供的类型

from typing import List, Optional, Set, Dict, Tuple

from pydantic import BaseModel


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None
    tags: List[str] = []
    address: Set[str] = set()
    phone: Tuple[int] = ()
    ext: Dict[str, str] = {}


item = Item(name="小菠萝", price=12.2)
print(item.dict())

 

输出结果

{
    "name": "小菠萝",
    "description": None,
    "price": 12.2,
    "tax": None,
    "tags": [],
    "address": set(),
    "phone": (),
    "ext": {}
}

 

Pydantic 嵌套模型

from typing import List
from pydantic import BaseModel

# 模型 1
class Foo(BaseModel):
    count: int
    size: float = None


# 模型 2
class Bar(BaseModel):
    apple = 'x'
    banana = 'y'

# 模型 3
class Spam(BaseModel):    
   # 字段类型是 Pydantic Model,这就是嵌套模型
    foo: Foo
    bars: List[Bar]


f = Foo(count=2)
b = Bar()
s = Spam(foo=f, bars=[b])

print(s.dict())

 

输出结果

{
    "bars": [
        {
            "apple": "x",
            "banana": "y"
        }
    ],
    "foo": {
        "count": 2,
        "size": 1
    }
}

  

FastAPI 中使用 Pydantic 嵌套模型

#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠萝测试笔记
# blog:  https://www.cnblogs.com/poloyy/
# time: 2021/9/19 9:40 下午
# file: 12_model.py
"""

from typing import List, Optional, Set, Dict, Tuple
import uvicorn
from pydantic import BaseModel
from fastapi import FastAPI

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None
    tags: List[str] = []
    address: Set[str] = set()
    phone: Tuple[int] = ()
    ext: Dict[str, str] = {}


# 模型一
class Image(BaseModel):
    url: str
    name: str


# 模型二
class Item(BaseModel):
    name: str
    price: float
    description: Optional[str] = None
    tags: Set[str] = set()
    # Image 模型组成的列表类型
    image: Optional[List[Image]] = None


@app.post("/items/{item_id}")
async def update_item(
        item_id: int,
        # 声明类型为:嵌套模型的 Item
        item: Item):
    results = {"item_id": item_id, "item": item}
    return results


if __name__ == "__main__":
    uvicorn.run(app="12_model:app", host="127.0.0.1", port=8080, reload=True, debug=True)

  

期望得到的请求体

{
  "name": "string",
  "price": 0,
  "description": "string",
  "tags": [],
  "image": [
    {
      "url": "string",
      "name": "string"
    }
  ]
}

 

重点

tags 虽然声明为 Set(),但在接口层面并没有集合这个概念,所以还是传数组 [ ] 格式哦,并不是传 { } 哦

但是!集合的特性仍然会保留:去重

 

FastAPI 给嵌套模型提供的功能

和前面讲的没什么区别

  • IDE 智能代码提示,甚至对于嵌套模型也支持
  • 数据转换
  • 数据验证
  • OpenAPI 文档

 

正确传参的请求结果

 

校验失败的请求结果

 

查看 Swagger API 文档

 

深层次嵌套模型

# 更深层嵌套
from typing import List, Optional, Set

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

# 模型一
class Image(BaseModel):
    url: str
    name: str

# 模型二
class Item(BaseModel):
    name: str
    price: float
    tags: Optional[Set[str]] = set()
    images: Optional[List[Image]] = None

# 模型三
class Offer(BaseModel):
    name: str
    description: Optional[str] = None
    items: List[Item]


@app.post("/offers/")
async def create_offer(offer: Offer):
    return offer

 

期望得到的请求体

{
    "name": "string",
    "description": "string",
    "items": [
        {
            "name": "string",
            "price": 0,"tags": [],
            "images": [
                {
                    "url": "string",
                    "name": "string"
                }
            ]
        }
    ]
}

  

正确传参的请求结果

 

IDE 提供的智能提示

即使是三层嵌套模型,也可以拥有丝滑般的代码提示哦

 

posted @ 2021-09-25 09:59  小菠萝测试笔记  阅读(592)  评论(0编辑  收藏  举报