Body字段驗證
之前我們提到過,Query和Path可以進行字段驗證,對長度和取值范圍等進行限制。Body中的JSON字段也具有同樣的驗證,只不過需要聲明在Model中,而不是參數(shù)中。
class Item(BaseModel):
name: str
description: Optional[str] = Field(
None, title="The description of the item", max_length=300
)
price: float = Field(..., gt=0, description="The price must be greater than zero")
tax: Optional[float] = None
使用Field()可以很好地滿足我們的需求。
復雜類型字段的驗證
tags: list = []表示普通的列表驗證,如果我們想要統(tǒng)一的類型(像數(shù)組那樣),我們可以使用typing的List來表示,例如tags: List[str] = []。
你過你要求數(shù)據(jù)不重復,那么也可以試試set,用typing中的Set來表示tags: Set[str] = set()
model嵌套
class Image(BaseModel):
url: str
name: str
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
tags: Set[str] = []
image: Image = None
使用model作為另一個model中字段的類型也是可以的。并且這也將很常用。
特殊類型驗證
pydantic提供了一些定義好的特殊類型,方便對各種內(nèi)容進行驗證。
from pydantic import BaseModel, UrlStr
class Image(BaseModel):
url: UrlStr
name: str
UrlStr便是一種可以驗證合法URL的預置類型
列表Body
如果您希望Body中的JSON,最外層是一個列表。那么您需要在參數(shù)中像如下一樣定義類型。
def create_multiple_images(images: List[Image]):
Dict的Body
除了Model,您也可以使用dict來接收Body。
@app.post("/index-weights/")
async def create_index_weights(weights: Dict[int, float]):
return weights
這種形式的類型標注,即可用字典來接收。當然JSON不支持int類型的key,不用擔心,fastapi會自動轉(zhuǎn)換。
Cookie參數(shù)
def read_items(*, ads_id: str = Cookie(None)):像這樣聲明,即可獲取Cookie參數(shù)。第一個值為默認值。
Header參數(shù)
def read_items(*, user_agent: str = Header(None)):可以接收Header中的參數(shù)。如果Header的一個字段具有多個值,可以使用def read_items(x_token: List[str] = Header(None)):這種形式
Response model
關于這部分內(nèi)容,請看前面關于fastapi源碼的解讀。
model之間的轉(zhuǎn)化
pydantic的model提供了.dict()方法,可以將字段導出為字典。這樣便實現(xiàn)模型之間的轉(zhuǎn)換。例如:
class UserIn(BaseModel):
username: str
password: str
email: EmailStr
class UserOut(BaseModel):
username: str
email: EmailStr
這兩個model之間的差別只有password,UserIn的定義需要如下形式
user_in = UserIn(
username="john",
password="secret",
email="john.doe@example.com"
)
而UserOut使用dict()導出可能是如下形式
{
'username': 'john',
'email': 'john.doe@example.com',
}
我們只需要user_in = UserIn(**user_out.dict(), password="secret")便可達到效果
反過來轉(zhuǎn)換,UserIn的dict中多余的參數(shù),會被UserOut忽略掉。
model的Union
@app.get("/items/{item_id}", response_model=Union[PlaneItem, CarItem])
async def read_item(item_id: str):
return items[item_id]
Union[PlaneItem, CarItem]使得response有更多的選擇余地。像response_model=List[Item]也是被允許的
Form表單
= Form(...),該類繼承于Body,用法一致。