美文网首页FastAPI 解读 by Gascognya
FastAPI 官方文档解读 (二)

FastAPI 官方文档解读 (二)

作者: Gascognya | 来源:发表于2020-09-05 23:32 被阅读0次

    Body字段验证

    之前我们提到过,QueryPath可以进行字段验证,对长度和取值范围等进行限制。Body中的JSON字段也具有同样的验证,只不过需要声明在Model中,而不是参数中。

    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 = []表示普通的列表验证,如果我们想要统一的类型(像数组那样),我们可以使用typingList来表示,例如tags: List[str] = []
    你过你要求数据不重复,那么也可以试试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提供了一些定义好的特殊类型,方便对各种内容进行验证。

    from pydantic import BaseModel, UrlStr 
    
    class Image(BaseModel):
        url: UrlStr
        name: str
    

    UrlStr便是一种可以验证合法URL的预置类型

    列表Body

    如果您希望Body中的JSON,最外层是一个列表。那么您需要在参数中像如下一样定义类型。

    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会自动转换。

    Cookie参数

    def read_items(*, ads_id: str = Cookie(None)):像这样声明,即可获取Cookie参数。第一个值为默认值。

    Header参数

    def read_items(*, user_agent: str = Header(None)):可以接收Header中的参数。如果Header的一个字段具有多个值,可以使用def read_items(x_token: List[str] = Header(None)):这种形式

    Response model

    关于这部分内容,请看前面关于fastapi源码的解读。

    FastAPI 源码阅读 (二) 路由

    model之间的转化

    pydantic的model提供了.dict()方法,可以将字段导出为字典。这样便实现模型之间的转换。例如:

    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")便可达到效果
    反过来转换,UserIn的dict中多余的参数,会被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,用法一致。

    相关文章

      网友评论

        本文标题:FastAPI 官方文档解读 (二)

        本文链接:https://www.haomeiwen.com/subject/hjofektx.html