新手必看: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)等进阶用法。

小夜