新手必看:FastAPI如何用Pydantic處理數據驗證

在Web開發中,數據驗證是確保應用安全、穩定運行的關鍵環節。比如用戶註冊時,需要驗證用戶名是否符合規則、年齡是否爲有效數字、郵箱格式是否正確等。如果驗證邏輯處理不當,輕則返回錯誤信息,重則可能導致程序崩潰或安全漏洞。FastAPI作爲一個高性能的Python Web框架,內置了Pydantic庫來處理數據驗證,它能讓數據驗證變得簡單且高效。

一、Pydantic是什麼?

Pydantic是一個Python庫,核心功能是數據驗證和設置管理。它通過定義數據模型(基於Python類型提示),自動檢查輸入數據是否符合模型規則,並在數據不合法時提供清晰的錯誤信息。FastAPI選擇Pydantic作爲數據驗證工具,是因爲它:
- 與Python原生類型提示兼容,無需額外學習複雜語法;
- 自動處理類型轉換(如字符串轉整數);
- 內置常見驗證邏輯(必填字段、默認值、格式驗證等);
- 錯誤信息友好,便於前端調試。

二、快速上手:定義第一個Pydantic模型

Pydantic模型通過繼承BaseModel定義,字段類型由Python類型提示指定。以下是一個簡單的用戶信息模型示例:

from pydantic import BaseModel

class User(BaseModel):
    name: str  # 字符串類型,必填(無默認值)
    age: int = 18  # 整數類型,可選(默認值18)
    email: str | None = None  # 字符串或None,可選(默認None)

關鍵點
- 必填字段:若字段沒有默認值(如name),則必須由用戶提供,否則FastAPI會返回“字段必填”錯誤;
- 可選字段:若字段有默認值(如ageemail),用戶可省略,使用默認值;
- 類型提示:支持intstrbool等基礎類型,也支持listdict等複雜類型(如hobbies: list[str])。

三、FastAPI中使用Pydantic處理請求數據

在FastAPI中,Pydantic模型最常見的用途是處理請求數據(如POST請求的請求體)。FastAPI會自動將請求體數據解析爲Pydantic模型,並驗證數據合法性。若驗證失敗,FastAPI會返回422錯誤和詳細的錯誤信息。

步驟1:定義Pydantic模型

from pydantic import BaseModel
from fastapi import FastAPI

# 定義用戶註冊請求模型
class UserCreate(BaseModel):
    name: str  # 必填,字符串
    age: int  # 必填,整數(無默認值)
    email: str  # 必填,字符串(假設後續用自定義驗證)

步驟2:在路由函數中使用模型

FastAPI路由函數的參數可直接指定爲Pydantic模型類型,FastAPI會自動解析請求體並驗證數據:

app = FastAPI()

@app.post("/users/register")
def register_user(user: UserCreate):
    # 驗證通過後,user是UserCreate模型實例,可直接使用
    return {
        "message": f"用戶註冊成功!歡迎,{user.name}{user.age}歲)",
        "email": user.email
    }

測試驗證效果

啓動FastAPI服務後,可通過POST請求測試驗證:
- 正常請求{"name": "小明", "age": 20, "email": "xiaoming@example.com"} → 返回成功信息;
- 錯誤請求{"name": "小紅", "age": "abc"}(age類型錯誤)→ FastAPI自動返回422錯誤,內容如下:

{
  "detail": [
    {
      "loc": ["body", "age"],
      "msg": "Input should be a valid integer",
      "type": "type_error.integer"
    }
  ]
}

四、響應數據驗證:確保返回格式正確

Pydantic也可用於驗證響應數據(如返回給前端的JSON),確保返回格式符合預期。例如,定義一個返回用戶信息的模型:

class UserResponse(BaseModel):
    id: int  # 用戶ID(假設由數據庫生成)
    name: str
    age: int
    email: str | None = None  # 可選字段

@app.get("/users/{user_id}", response_model=UserResponse)
def get_user(user_id: int):
    # 模擬從數據庫獲取用戶數據
    user_data = {
        "id": user_id,
        "name": "測試用戶",
        "age": 25,
        "email": "test@example.com"
    }
    return user_data  # FastAPI會自動驗證返回數據是否符合UserResponse模型

關鍵點
- 使用response_model=UserResponse參數,FastAPI會自動將返回數據序列化爲UserResponse模型格式;
- 若返回數據包含模型外字段(如額外的token),FastAPI會自動過濾,確保只返回模型中定義的字段。

五、進階:自定義驗證規則

Pydantic支持更復雜的驗證需求,如限制數值範圍、自定義格式(如郵箱)等,通過以下方式實現:

1. 使用Field設置字段約束

通過Field可指定字段的額外規則(如最小/最大長度、正則表達式):

from pydantic import BaseModel, Field, EmailStr

class UserCreate(BaseModel):
    name: str = Field(..., min_length=2, max_length=20)  # 姓名長度2-20
    age: int = Field(gt=0, lt=150)  # 年齡0 < age < 150
    email: EmailStr = Field(...)  # 自動驗證郵箱格式(需安裝pydantic[email])

2. 自定義驗證函數

使用@field_validator裝飾器定義自定義驗證邏輯(如郵箱格式):

from pydantic import BaseModel, field_validator
import re

class UserCreate(BaseModel):
    name: str
    age: int
    email: str

    @field_validator('email')  # 驗證email字段
    def email_format(cls, v):
        if not re.match(r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$', v):
            raise ValueError('郵箱格式錯誤')
        return v  # 驗證通過需返回原始值

六、總結

Pydantic在FastAPI中扮演了“數據驗證管家”的角色,通過以下優勢讓API開發更簡單:
- 自動驗證:無需手動寫if-else判斷,FastAPI+Pydantic自動攔截非法數據;
- 錯誤提示:清晰的錯誤信息幫助前端快速定位問題;
- 類型安全:避免因數據類型錯誤導致的程序崩潰;
- 靈活擴展:支持基礎類型、複雜結構、自定義規則等,滿足各種驗證需求。

對於FastAPI新手,掌握Pydantic的基礎使用(定義模型、路由參數、錯誤處理)是開發安全、健壯API的必備技能。

提示:若需進一步學習,可查閱Pydantic官方文檔(https://docs.pydantic.dev/latest/),瞭解複雜類型(如嵌套模型、列表嵌套)、ORM集成(orm_mode=True)等進階用法。

小夜