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
相关产品推荐
相关产品推荐

