Body - Nested Models
可以将属性定义为子类型,例如 python 的 list
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
tags: list = []
@app.put("/items/{item_id}")
async def update_item(*, item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
tags
表示实体列表,尽管没有显式声明每个实体的类型
List fields with subtype
可以通过 python 的 typing
标准库来声明具有子类型的列表,例如
from typing import List
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
tags: List[str] = []
@app.put("/items/{item_id}")
async def update_item(*, item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
Set types
使用 set
类型可以声明一组不重复的实体
from typing import Set
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
tags: Set[str] = set()
@app.put("/items/{item_id}")
async def update_item(*, item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
通过 set
,即使接收到一组重复数据,也将会被自动转化为一组没有重复的实体
这些也会被自动加入注解
Nested Models
Pydantic
模型的每一个属性都有其类型,并且这些类型可以是另一个 Pydantic
模型,因此可以声明嵌套的 JSON
对象,并且这些对象可以有特定的属性名称,类型和验证
所有这些都可以被任意嵌套
from typing import Set
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
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
@app.put("/items/{item_id}")
async def update_item(*, item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
在上面的例子中,Image
模型作为 Item
模型的一个属性
FastAPI 期望的 request body 类似于
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2,
"tags": ["rock", "metal", "bar"],
"image": {
"url": "http://example.com/baz.jpg",
"name": "The Foo live"
}
}
仅仅使用上述声明以及 FastAPI,将可以获得
- IDE 支持
- 数据自动转换
- 数据验证
- 自动文档
Special types and validation
除了类似于 str
,int
,float
普通的单一类型,还可以使用继承于 str
的更加复杂的类型
例如,在 Image
模型里面,我们可以用 HttpUrl
类型来代替普通的 str
,例如
from typing import Set
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
tags: Set[str] = []
image: Image = None
@app.put("/items/{item_id}")
async def update_item(*, item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
url
属性将会自动检查是否是合法的 URL
,并且在自动文档中标注
Attributes with lists of submodels
Ptdantic
模型同样可以作为 list
,set
等的子类型,例如
from typing import List, Set
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
tags: Set[str] = []
images: List[Image] = None
@app.put("/items/{item_id}")
async def update_item(*, item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
上面的例子将会期待 body
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2,
"tags": [
"rock",
"metal",
"bar"
],
"images": [
{
"url": "http://example.com/baz.jpg",
"name": "The Foo live"
},
{
"url": "http://example.com/dave.jpg",
"name": "The Baz"
}
]
}
Deeply nested models
可以定义任意深度嵌套的模型
from typing import List, Set
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
tags: Set[str] = []
images: List[Image] = None
class Offer(BaseModel):
name: str
description: str = None
price: float
items: List[Item]
@app.post("/offers/")
async def create_offer(*, offer: Offer):
return offer
Bodies of pure lists
如果希望 JSON body 的顶层值是一个 JSON array
,可以如下声明
from typing import List
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
@app.post("/images/multiple/")
async def create_multiple_images(*, images: List[Image]):
return images
Bodies of arbitrary dict
s
同样可以使用具有某些类型的键和某些类型的值的 dict
来声明 request body
可以被用在如果某些键和值名字不确定的情况,例如
from typing import Dict
from fastapi import FastAPI
app = FastAPI()
@app.post("/index-weights/")
async def create_index_weights(weights: Dict[int, float]):
return weights
在上述例子中,只要是整形的 key
和浮点型的 value
就会被接受
注:JSON 只支持 str
作为键,但是 Pydantic
模型可以对数据进行自动转换。即,即使客户端只支持发送字符串作为键,只要这些键只包含纯整数,Pydantic
就会进行自动转化和验证