前言
有多個模型,且請求/響應需要聲明多個模型的時候,可以根據不同使用場景結合 typing 庫里面的 Union、List 來達到目的
Union
作用
聯合類型,詳細教程
使用 Union 時,建議首先包含具體的類型,然后是不太具體的類型
實際代碼
#!usr/bin/env python # -*- coding:utf-8 _*- """ # author: 小菠蘿測試筆記 # blog: https://www.cnblogs.com/poloyy/ # time: 2021/9/22 8:28 上午 # file: 19_extra models.py """ import uvicorn from fastapi import FastAPI from typing import Optional, Union, List, Dict from pydantic import BaseModel, EmailStr app = FastAPI() class BaseItem(BaseModel): description: str type: str class CarItem(BaseItem): # 給了個默認值 type = "car" class PlaneItem(BaseItem): type = "plane" size: int items = { "item1": {"description": "All my friends drive a low rider", "type": "car"}, "item2": { "description": "Music is my aeroplane, it's my aeroplane", "type": "plane", "size": 5, }, } @app.get("/items/{item_id}", response_model=Union[PlaneItem, CarItem]) async def read_item(item_id: str):
# item_id 作為鍵去 items 中找到對應的值 return items[item_id] if __name__ == "__main__": uvicorn.run(app="20_union_list_dict:app", host="127.0.0.1", port=8080, reload=True, debug=True)
item_id = item1 的請求結果
item_id = item2 的請求結果
List
class Item(BaseModel): name: str description: str items = [ {"name": "Foo", "description": "There comes my hero"}, {"name": "Red", "description": "It's my aeroplane", "size": 123}, # 多了個 size 字段 ] @app.get("/items/", response_model=List[Item]) async def read_items(): return items
正確傳參的請求結果
返回的是一個數組
假設響應內容多了個 size
items[1] 多了個 size 字段,但因為響應模型並不包含 size,所以最終返回的數據也不會包含 size
假設響應內容不包含 description
raise ValidationError(errors, field.type_) pydantic.error_wrappers.ValidationError: 1 validation error for Item response -> 1 -> description field required (type=value_error.missing)
- 因為響應模型聲明了 name、description 都是必傳參數,假設不傳就會報錯
- 但又因為是響應數據有問題,代表應用程序(服務端)有問題,所以客戶端發送請求就會報 500