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

FastAPI/Pydantic单路由如何同时支持单值和数组类型请求参数解析

实现方法

你可以通过给Pydantic模型添加自定义字段验证器实现需求,不管入参是单个字符串还是字符串数组,都会自动转为列表类型,不会触发类型校验错误。

完整代码示例(适配Pydantic V2 主流版本)

from pydantic import BaseModel, field_validator
from typing import List, Any
from fastapi import APIRouter

router = APIRouter()

class Create(BaseModel):
    code: List[str] = []
    args: List[str] = []

    @field_validator("code", "args", mode="before")
    @classmethod
    def to_list(cls, v: Any) -> Any:
        # 非列表类型直接包装为单元素列表
        if not isinstance(v, list):
            return [v]
        return v

@router.post('/new', status_code=201)
async def create_project(data: Create):
    # 此处拿到的code和args永远是列表类型
    return {"code": data.code, "args": data.args}

验证器加了mode="before"参数,会在Pydantic默认类型校验前执行,先完成类型转换再走List[str]的格式校验,不会抛出"期望列表类型"的错误。

如果你使用的是Pydantic V1版本

把验证器替换为@validator即可,逻辑完全一致:

from pydantic import BaseModel, validator

class Create(BaseModel):
    code: List[str] = []
    args: List[str] = []

    @validator("code", "args", pre=True)
    @classmethod
    def to_list(cls, v):
        if not isinstance(v, list):
            return [v]
        return v

效果验证

你给出的4种请求格式都可以正常解析,最终路由内拿到的字段都是列表:

  • 传入{"code": "code", "args": "arg"} → 得到 code=["code"], args=["arg"]
  • 传入{"code": ["code"], "args": "arg"} → 得到 code=["code"], args=["arg"]
  • 传入{"code": ["code"], "args": ["arg"]} → 得到 code=["code"], args=["arg"]
  • 传入{"code": "code", "args": ["arg"]} → 得到 code=["code"], args=["arg"]

如果需要兼容传null的场景,只需修改验证器逻辑,空值默认返回空列表即可:

@field_validator("code", "args", mode="before")
@classmethod
def to_list(cls, v: Any) -> Any:
    if v is None:
        return []
    if not isinstance(v, list):
        return [v]
    return v

内容的提问来源于stack exchange,提问作者DuckQueen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 09:45:00