FastAPI(14)- 路径操作函数参数的类型是一个嵌套 Pydantic Model 的使用场景
带有类型参数的字段
Python 有一种特定的方法来声明具有内部类型或类型参数的列表
其实前面都见过,就是
List[str]
Set[str]
Tuple[str]
Dict[str, int]
- List、Set、Tuple、Dict 都是从 typing 模块中导入的
- typing 常见类型提示,详细教程:https://www.cnblogs.com/poloyy/p/15150315.html
在 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 提供的智能提示
即使是三层嵌套模型,也可以拥有丝滑般的代码提示哦