FastApi學習-03

多個request-body

class Item1(BaseModel):
    name: str

class Item2(BaseModel):
    name: str

@app.post('/request_body01')
def request_body01(*, item1: Item1, item2: Item2):
    return [item1, item2]

@app.post("/request_body02")
def request_body02(*, item1: Item1, item2: Item2, item3: str = Body(...)):
    return [item1, item2, item3]

接受多個request-body的方法除了使用繼承BaseModel,還可以使用FastApi提供的Body方法,和上一個學習目錄中提到Path,Query類似,當定義成str類型的,可以使用min_length, max_length限制,當定義成int類型時,可以使用ge,gt,le,lt等限制。除此之外,Body還提供了一個embed的參數,用於只有request-body參數時,將key嵌套進request-body中,形如:

@app.post("/request_body03")
def request_body03(item1: Item1 = Body(..., embed=True)):
    return item1

這種情況下,調用時傳入的request-body是{“item1”: {"name": "***"}}而不是{"name": "***"}

BaseModel中Field

接受request-body參數時可以用繼承與BaseModel的類來實現,但是沒有對類中的參數的數據校驗,而Field提供了這樣的功能。

注意:Field與Body,Query,Path的不同之處在於Field引自於Pydantic而不是FastApi。

class Item3(BaseModel):
    name: str = Field(..., min_length=3)
    age: int = Field(..., ge=0)

@app.post("/request_body04")
def request_body04(item: Item3):
    return item

BaseModel中的嵌套模型

class Item3(BaseModel):
    list1: list = []
    list2: List = []
    list3: List[int] = [1]

數組類型的定義可以使用list和由typing導入的List,但是隻要指定數組內元素的數據類型,只能使用List來聲明。

class Item4(BaseModel):
    set1: set = set()
    set2: Set = set()
    set3: Set[str] = set()

集合的定義和數組一樣

class Item5(BaseModel):
    set1: set = set()
    set2: Set = set()
    set3: Set[str] = set()
    list1: Item4 = None
    list2: List[Item4] = None

也可以使用別的model類來聲明自己的屬性,也可以定義成嵌套類型的子屬性,支持多層嵌套。

@app.post("/request_body06")
def reuqest_body06(item: List[Item1]):
    return item

上述方式接受一個數據類型的model而不是字典類型的model。

@app.post("/request_body07")
def reuqest_body07(dict1: Dict[str, int]):
    return dict1

當不確定具體的key的時候,可以使用Dict的方法

Api文檔增加樣例

class Item6(BaseModel):
    name: str = Field(..., example="wang")
    age: int = Field(..., example=1)

class Item7(BaseModel):
    sex: int

    class Config:
        schema_extra = {
            "example": {"sex": 1}
        }

@app.post("/request_body08")
def request_body08(item1: Item6, item2: Item7):
    return [item1, item2]

使用Field的example參數或者BaseModel的Config都可以實現未api文檔增加樣例,如果沒有上述設置了樣例但是設置了默認值,也可實現樣例。

數據類型

除了標準庫裏面的int, str, float, bool,還支持其他的數據類型。

UUID(from uuid import UUID)形如"3fa85f64-57174562-b3fc-2c963f66afa6", 在調用的時候,中間的分隔符"-"可以去掉一個或多個,但是在接口識別的時候,仍會有分隔符"-"。

datetime(from datetime import datetime): 符合ISO8601格式的時間字符串,例如”2020-01-01 12:00:00“

date(from datetime import date): 符合ISO8601格式的日期字符串,例如”2020-01-01“

time(from datetime import time): 符合ISO8601格式的時間字符串,例如”12:00:00“

timedelta(from datetime import timedelta):相當於float類型的秒數

frozenset: 在請求端是以數組的形式存在,在響應端和Set集合是一樣,但是frozenset不允許進行集合的增減,是一個只讀集合,還存在一個問題:如果設置了frozenset之後,redoc和swagger都會拋出異常,無法使用。我的解決方案是直接修改源碼,在pydantic/schema.py中,爲field_class_to_schema這個元組增加frozenset元素

(frozenset, {'type': 'array', 'items': {}, 'uniqueItems': True}),

bytes:接受str類型,轉化成bytes類型,‘123’ -> b'123'

Decimal: 和float相似。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章