请求体 #
什么是请求体? #
请求体是客户端发送给服务器的数据,通常用于 POST、PUT、PATCH 等请求。
text
┌─────────────────────────────────────────────────────────────┐
│ 请求体位置 │
├─────────────────────────────────────────────────────────────┤
│ │
│ POST /items HTTP/1.1 │
│ Content-Type: application/json │
│ │
│ { ← 请求体 │
│ "name": "Item 1", │
│ "price": 10.5 │
│ } │
│ │
└─────────────────────────────────────────────────────────────┘
Pydantic 模型 #
基本模型 #
python
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
使用模型 #
python
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
@app.post('/items/')
def create_item(item: Item):
return item
模型方法 #
python
@app.post('/items/')
def create_item(item: Item):
item_dict = item.model_dump() # 转换为字典
item_json = item.model_dump_json() # 转换为 JSON 字符串
return item_dict
字段类型 #
基本类型 #
python
from pydantic import BaseModel
class Item(BaseModel):
name: str # 字符串
price: float # 浮点数
quantity: int # 整数
is_available: bool # 布尔值
tags: list[str] # 字符串列表
metadata: dict[str, str] # 字典
可选类型 #
python
from typing import Optional
class Item(BaseModel):
name: str
description: Optional[str] = None
# 或使用 Python 3.10+ 语法
description: str | None = None
默认值 #
python
class Item(BaseModel):
name: str
price: float = 0.0
quantity: int = 1
tags: list[str] = []
字段验证 #
Field 函数 #
python
from pydantic import BaseModel, Field
class Item(BaseModel):
name: str = Field(..., min_length=2, max_length=50)
price: float = Field(..., gt=0, description='Price must be positive')
quantity: int = Field(default=1, ge=0)
tax: float | None = Field(default=None, le=0.5)
字段验证约束 #
text
┌─────────────────────────────────────────────────────────────┐
│ 字段验证约束 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 字符串: │
│ min_length 最小长度 │
│ max_length 最大长度 │
│ pattern 正则表达式 │
│ │
│ 数值: │
│ gt 大于 ge 大于等于 │
│ lt 小于 le 小于等于 │
│ multiple_of 倍数 │
│ │
│ 列表: │
│ min_length 最少元素数 │
│ max_length 最多元素数 │
│ │
│ 通用: │
│ default 默认值 │
│ default_factory 默认工厂函数 │
│ title 标题 │
│ description 描述 │
│ examples 示例 │
│ │
└─────────────────────────────────────────────────────────────┘
字符串验证示例 #
python
from pydantic import BaseModel, Field
class User(BaseModel):
username: str = Field(
...,
min_length=3,
max_length=20,
pattern='^[a-zA-Z0-9_]+$',
description='Username must be alphanumeric with underscores'
)
email: str = Field(
...,
pattern=r'^[\w\.-]+@[\w\.-]+\.\w+$'
)
数值验证示例 #
python
class Product(BaseModel):
name: str
price: float = Field(..., gt=0, description='Price must be positive')
discount: float = Field(default=0, ge=0, le=1)
quantity: int = Field(default=0, ge=0)
rating: float = Field(default=5.0, ge=0, le=5)
列表验证示例 #
python
class Order(BaseModel):
items: list[str] = Field(..., min_length=1, max_length=10)
quantities: list[int] = Field(default=[], min_length=1)
特殊类型 #
EmailStr #
python
from pydantic import BaseModel, EmailStr
class User(BaseModel):
email: EmailStr
HttpUrl #
python
from pydantic import BaseModel, HttpUrl
class Website(BaseModel):
url: HttpUrl
日期时间类型 #
python
from datetime import datetime, date, time, timedelta
from pydantic import BaseModel
class Event(BaseModel):
created_at: datetime
event_date: date
start_time: time
duration: timedelta
枚举类型 #
python
from enum import Enum
from pydantic import BaseModel
class Status(str, Enum):
pending = 'pending'
approved = 'approved'
rejected = 'rejected'
class Item(BaseModel):
status: Status
嵌套模型 #
模型嵌套 #
python
from pydantic import BaseModel
class Image(BaseModel):
url: str
name: str
class Item(BaseModel):
name: str
description: str | None = None
price: float
image: Image | None = None
@app.post('/items/')
def create_item(item: Item):
return item
请求体:
json
{
"name": "Item 1",
"price": 10.5,
"image": {
"url": "http://example.com/image.jpg",
"name": "Product Image"
}
}
列表嵌套 #
python
class Item(BaseModel):
name: str
price: float
class Order(BaseModel):
items: list[Item]
total: float
@app.post('/orders/')
def create_order(order: Order):
return order
深层嵌套 #
python
class Address(BaseModel):
street: str
city: str
country: str
class User(BaseModel):
name: str
address: Address
class Order(BaseModel):
user: User
items: list[Item]
自定义验证器 #
field_validator #
python
from pydantic import BaseModel, field_validator
class User(BaseModel):
name: str
username: str
@field_validator('username')
@classmethod
def username_alphanumeric(cls, v: str) -> str:
if not v.isalnum():
raise ValueError('must be alphanumeric')
return v.lower()
model_validator #
python
from pydantic import BaseModel, model_validator
class User(BaseModel):
password: str
confirm_password: str
@model_validator(mode='after')
def passwords_match(self):
if self.password != self.confirm_password:
raise ValueError('passwords do not match')
return self
验证器示例 #
python
from pydantic import BaseModel, field_validator
class Item(BaseModel):
name: str
price: float
@field_validator('name')
@classmethod
def name_must_not_be_empty(cls, v: str) -> str:
if not v.strip():
raise ValueError('name cannot be empty')
return v.strip()
@field_validator('price')
@classmethod
def price_must_be_positive(cls, v: float) -> float:
if v <= 0:
raise ValueError('price must be positive')
return round(v, 2)
请求体示例 #
添加示例 #
python
from pydantic import BaseModel, Field
class Item(BaseModel):
name: str = Field(..., examples=['Foo'])
description: str | None = Field(None, examples=['A very nice Item'])
price: float = Field(..., examples=[35.4])
tax: float | None = Field(None, examples=[3.2])
模型示例 #
python
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
model_config = {
'json_schema_extra': {
'examples': [
{
'name': 'Foo',
'description': 'A very nice Item',
'price': 35.4,
'tax': 3.2,
}
]
}
}
请求体字段 #
Body 函数 #
python
from fastapi import FastAPI, Body
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
@app.put('/items/{item_id}')
def update_item(
item_id: int,
item: Item,
importance: int = Body(..., gt=0)
):
return {'item_id': item_id, 'item': item, 'importance': importance}
嵌入请求体 #
python
@app.put('/items/{item_id}')
def update_item(item_id: int, item: Item = Body(..., embed=True)):
return {'item_id': item_id, 'item': item}
请求体格式:
json
{
"item": {
"name": "Foo",
"price": 45.2
}
}
多个请求体 #
多个模型 #
python
class Item(BaseModel):
name: str
price: float
class User(BaseModel):
username: str
full_name: str | None = None
@app.put('/items/{item_id}')
def update_item(item_id: int, item: Item, user: User):
return {'item_id': item_id, 'item': item, 'user': user}
请求体格式:
json
{
"item": {
"name": "Foo",
"price": 45.2
},
"user": {
"username": "john",
"full_name": "John Doe"
}
}
请求体 + 表单 + 文件 #
python
from fastapi import FastAPI, Form, File, UploadFile
from pydantic import BaseModel
app = FastAPI()
@app.post('/items/')
def create_item(
name: str = Form(...),
price: float = Form(...),
file: UploadFile = File(...)
):
return {
'name': name,
'price': price,
'filename': file.filename
}
模型配置 #
Config 类 #
python
from pydantic import BaseModel, ConfigDict
class Item(BaseModel):
model_config = ConfigDict(
str_strip_whitespace=True,
str_min_length=1,
validate_assignment=True,
extra='forbid'
)
name: str
price: float
常用配置 #
text
┌─────────────────────────────────────────────────────────────┐
│ 模型配置选项 │
├─────────────────────────────────────────────────────────────┤
│ │
│ str_strip_whitespace 去除字符串空白 │
│ str_min_length 字符串最小长度 │
│ str_max_length 字符串最大长度 │
│ validate_assignment 赋值时验证 │
│ extra 额外字段处理 │
│ 'ignore' 忽略 │
│ 'forbid' 禁止 │
│ 'allow' 允许 │
│ alias_generator 别名生成器 │
│ populate_by_name 允许通过字段名填充 │
│ │
└─────────────────────────────────────────────────────────────┘
完整示例 #
python
from datetime import datetime
from typing import Optional
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field, EmailStr, field_validator
app = FastAPI()
class Address(BaseModel):
street: str = Field(..., min_length=5)
city: str = Field(..., min_length=2)
country: str = Field(..., min_length=2)
class User(BaseModel):
username: str = Field(
...,
min_length=3,
max_length=20,
pattern='^[a-zA-Z0-9_]+$'
)
email: EmailStr
full_name: Optional[str] = Field(None, min_length=2)
age: int = Field(..., ge=0, le=150)
address: Optional[Address] = None
created_at: datetime = Field(default_factory=datetime.now)
@field_validator('username')
@classmethod
def username_lowercase(cls, v: str) -> str:
return v.lower()
class UserCreate(User):
password: str = Field(..., min_length=8)
users_db: dict[str, User] = {}
@app.post('/users/', response_model=User, status_code=201)
def create_user(user: UserCreate):
if user.username in users_db:
raise HTTPException(status_code=400, detail='Username already exists')
user_data = user.model_dump(exclude={'password'})
users_db[user.username] = User(**user_data)
return users_db[user.username]
@app.get('/users/{username}', response_model=User)
def get_user(username: str):
if username not in users_db:
raise HTTPException(status_code=404, detail='User not found')
return users_db[username]
下一步 #
现在你已经掌握了请求体处理,接下来学习 Pydantic 基础,深入了解数据验证!
最后更新:2026-03-29