FastAPI中Query参数接收List[str]需用Query(...)声明必填,可自动将单字符串转为单元素列表;若用Query(default=None)则报错,因Pydantic无法将str解析为list。
![fastapi 如何让 query 参数支持 list[str] 但允许单值输入](https://img.php.cn/upload/article/001/242/473/176925243749443.png)
FastAPI 中 Query 参数接收 List[str] 但兼容单个字符串输入
FastAPI 默认对Query 使用类型注解 List[str] 时,要求客户端必须传多个同名参数(如 ?tag=a&tag=b),否则会报 value is not a valid list 错误。但实际中常需要支持单值(?tag=foo)和多值(?tag=foo&tag=bar)两种写法。
关键在于:不能只靠类型注解,得配合 default 和 ...(Ellipsis) 显式声明可选性,并让 FastAPI 知道该字段允许“自动展开单值为列表”。
- 用
Query(default=...)声明必填(或Query(default=[])声明可选空列表) - 类型注解保持
List[str],FastAPI 会自动把单个字符串转成长度为 1 的列表 - 确保客户端传参方式正确:单值用
?key=value,多值用?key=a&key=b(不是?key=a,b) - 如果想支持逗号分隔的单字符串(如
?tag=a,b,c),需额外手动解析,FastAPI 不默认处理
为什么直接写 List[str] 有时会报错?
常见错误现象是收到value is not a valid list 或 type_error.list,本质是 Pydantic 在校验时发现传入的是 str 而非 list —— 这通常发生在:
- 你用了
Query(default=None)+List[str],但没设default=...,导致 FastAPI 无法推断是否允许多值 -
前端发请求时用了
?tags=foo,但后端定义成了tags: Optional[List[str]] = None,此时 Pydantic 尝试把"foo"当作List解析失败 - 漏了
from typing import List(Python 3.9+ 可用list[str],但 FastAPI 0.103+ 才完全支持)
完整可运行示例
from fastapi import FastAPI, Query
from typing import List
app = FastAPI()
@app.get("/search/")
def search(tags: List[str] = Query(..., description="标签列表,支持单值或多值")):
return {"tags": tags}
调用效果:
-
GET /search/?tags=python→{"tags": ["python"]} -
GET /search/?tags=python&tags=fastapi&tags=web→{"tags": ["python", "fastapi", "web"]} -
GET /search/(无 tags)→ 返回 422,提示缺少必填字段
想支持 ?tags=a,b 形式怎么办?
FastAPI 不原生支持逗号分隔字符串自动转列表。若必须接受这种格式,需手动处理:- 把参数类型改为
str,再在函数内用.split(",")和strip() - 或者用自定义依赖项封装解析逻辑,避免每个接口重复写
- 注意空字符串、多余空格、编码问题(如中文逗号)
最易忽略的一点:文档(Swagger UI)里不会自动显示“支持单值”,它只按 List[str] 渲染为多输入框。如果对外暴露 API,得在 description 或额外文档里说明兼容单值写法。










