likes
comments
collection
share

(三)FastAPI 的数据验证与序列化

作者站长头像
站长
· 阅读数 140

在现代 Web 开发中,数据验证和序列化是不可或缺的部分。FastAPI 通过集成 Pydantic,为数据验证和序列化提供了强大且易用的功能。本文将详细介绍如何在 FastAPI 中进行数据验证和序列化,帮助你达到高级程序员的水平。

1. Pydantic 简介

Pydantic(/paɪˈdæntɪk/)是一个数据验证和解析库,基于 Python 类型提示。它允许你通过定义数据模型,自动进行数据验证和解析。Pydantic 的主要特性包括:

  • 类型提示支持:使用标准的 Python 类型提示。
  • 数据验证:自动验证传入的数据,并提供详细的错误信息。
  • 数据解析:自动将数据解析为定义的类型。

2. 使用 Pydantic 进行数据验证

在 FastAPI 中,Pydantic 模型通常用于请求体、响应体以及路径参数和查询参数的验证。以下是一些具体的用法示例。

定义 Pydantic 模型:

from pydantic import BaseModel, Field
from typing import Optional

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

示例解析:

  • name: 必填字段,类型为 str。
  • description: 可选字段,类型为 str,默认值是None,并添加了字段说明和最大长度限制。
  • price: 必填字段,类型为 float,并添加了大于零的验证。
  • tax: 可选字段,类型为 float,默认值是None

3. 请求体数据验证

示例:创建一个包含请求体的路由

from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional

app = FastAPI()

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

@app.post("/items/")
async def create_item(item: Item):
    return item

在这个示例中,create_item路由会接收一个Item类型的请求体。FastAPI 会自动将请求体的数据解析并验证为Item类型,如果验证失败,会自动返回一个详细的错误响应。

(三)FastAPI 的数据验证与序列化 HTTP 状态码 422 代表 "Unprocessable Entity"(无法处理的实体)。这是一个 WebDAV 扩展状态码,表示服务器理解请求的内容类型,并且请求的语法也是正确的,但是服务器无法处理所包含的指令。在 FastAPI 中,状态码 422 通常出现在请求数据验证失败的情况下。FastAPI 使用 Pydantic 来验证请求数据,如果传入的数据不符合预期的格式或规则,FastAPI 会返回一个 422 状态码,并包含详细的错误信息。

4. 响应体数据验证与序列化

示例:定义响应模型

from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional

app = FastAPI()

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

class ItemResponse(BaseModel):
    item: Item
    message: str

@app.post("/items/", response_model=ItemResponse)
async def create_item(item: Item):
    return {"item": item, "message": "Item created successfully"}

在这个示例中,create_item路由返回的数据会被自动验证和序列化为ItemResponse类型。如果返回的数据不符合ItemResponse模型定义,FastAPI 会自动返回一个错误响应。

(三)FastAPI 的数据验证与序列化

5. 路径参数和查询参数的数据验证

示例:验证路径参数和查询参数

from fastapi import FastAPI, Path, Query
from pydantic import BaseModel
from typing import Optional

app = FastAPI()

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

@app.get("/items/{item_id}")
async def read_item(item_id: int = Path(..., gt=0, description="The ID of the item to get"), q: Optional[str] = Query(None, max_length=50)):
    return {"item_id": item_id, "q": q}

在这个示例中,item_id是一个路径参数,并且被验证为大于 0。q是一个查询参数,最大长度为50。FastAPI 会自动进行这些验证,并返回相应的错误信息。

6. 高级用法

复杂嵌套模型

  • Pydantic 支持复杂嵌套模型,使得你可以创建更复杂的数据结构。
from pydantic import BaseModel
from typing import List, Optional

class SubItem(BaseModel):
    name: str
    price: float

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None
    subitems: List[SubItem]

@app.post("/items/")
async def create_item(item: Item):
    return item

(三)FastAPI 的数据验证与序列化

联合类型 (Union) 和自定义验证器

  • Pydantic 还支持使用联合类型 (Union) 和自定义验证器。
from pydantic import BaseModel, validator, ValidationError
from typing import Union

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

    @validator("price")
    def check_price(cls, value):
        if value <= 0:
            raise ValueError("Price must be greater than zero")
        return value

class DiscountedItem(BaseModel):
    item: Item
    discount: Union[float, int]

@app.post("/discounted-items/")
async def create_discounted_item(discounted_item: DiscountedItem):
    return discounted_item

处理复杂数据

  • 当你需要处理复杂数据时,Pydantic 可以帮助你简化代码并保证数据的正确性。
from pydantic import BaseModel, ValidationError
from typing import List

class User(BaseModel):
    id: int
    name: str
    friends: List[int]

class Post(BaseModel):
    id: int
    title: str
    content: str
    author: User

@app.post("/posts/")
async def create_post(post: Post):
    return post

7. 错误处理与自定义错误信息

当数据验证失败时,FastAPI 会返回详细的错误信息。你可以自定义这些错误信息来提供更好的用户体验。

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field, ValidationError

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float = Field(..., gt=0, description="The price must be greater than zero")

@app.post("/items/")
async def create_item(item: Item):
    try:
        item = Item(**item.dict())
    except ValidationError as e:
        raise HTTPException(status_code=400, detail=e.errors())
    return item

通过深入了解和掌握 FastAPI 的数据验证和序列化功能,你可以更高效地开发和维护你的 Web 应用。Pydantic 的强大功能使得数据验证和解析变得简洁而高效,结合 FastAPI 的自动文档生成和类型提示支持,你可以创建出性能优越且易于维护的 API。

希望这篇文章能帮助你更深入地理解和使用 FastAPI,实现更高级的编程技巧和实践。

转载自:https://juejin.cn/post/7379074566032752677
评论
请登录