You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Accept请求头在解析前设置FastAPI不可变Pydantic模型字段默认值?

根据Accept请求头为不可变Pydantic模型设置动态默认值

可以实现,核心是在FastAPI将请求体解析为Item对象之前,先读取Accept请求头并注入对应的默认值,同时保证模型的不可变性。下面是具体的实现方案:

实现思路

通过自定义依赖函数(Dependency) 预处理请求数据:

  1. 读取原始请求体和Accept头
  2. 根据Accept头匹配对应的默认shape_mode值
  3. 若请求体未提供shape_mode,则注入默认值
  4. 将处理后的数据解析为不可变的Item模型实例

完整代码示例

from enum import Enum
from fastapi import FastAPI, Request, Depends
from pydantic import BaseModel


class ShapeModeEnum(str, Enum):
    schematic = "schematic"
    realistic = "realistic"


class Item(BaseModel):
    name: str
    shape_mode: ShapeModeEnum

    class Config:
        allow_mutation = False
        extra = "forbid"
        strict = True
        validate_assignment = True


app = FastAPI()

RESPONSE_CLASSES = {
    "application/json": "schematic",
    "image/png": "realistic",
}


async def get_item_with_default_shape_mode(request: Request):
    # 读取请求体JSON数据
    body = await request.json()
    # 获取Accept头,默认使用application/json
    accept_header = request.headers.get("accept", "application/json").lower()
    
    # 匹配对应的默认shape_mode(支持多值Accept头的简单匹配)
    default_shape_mode = RESPONSE_CLASSES["application/json"]
    for media_type, mode in RESPONSE_CLASSES.items():
        if media_type in accept_header:
            default_shape_mode = mode
            break
    
    # 注入默认值(仅当请求体未提供时)
    if "shape_mode" not in body:
        body["shape_mode"] = default_shape_mode
    
    # 解析为不可变的Item实例
    return Item(**body)


@app.post("/item")
async def create_item(item: Item = Depends(get_item_with_default_shape_mode)):
    return item

关键细节说明

  • 处理多值Accept头:比如用户发送Accept: application/json, image/png时,会匹配第一个符合条件的媒体类型并设置对应默认值
  • 保证模型不可变性:Item模型的allow_mutation=False配置确保实例创建后无法修改,所有默认值注入都在模型解析前完成
  • 兼容默认情况:若请求未携带Accept头,默认使用application/json对应的schematic值

内容的提问来源于stack exchange,提问作者Joost Dübken

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 21:25:37