FastAPI解析嵌套数组格式HTTP GET请求URL参数的问题求助
解决FastAPI中PHP风格嵌套URL查询参数的解析问题
我刚好遇到过类似的场景,FastAPI默认对products[0][id]这种PHP风格的嵌套查询参数支持不够直接——这也是你之前用List或者直接传products参数返回None的原因,FastAPI默认期望的是点分隔的嵌套格式(比如products[0].id),而非方括号的结构。
下面给你两种更优的解决方案,根据你的场景选择:
方案一:自定义依赖项(推荐,兼容现有参数格式)
这种方式可以直接解析你当前的参数格式,同时利用Pydantic做类型验证和转换,代码更健壮可复用:
首先定义产品的Pydantic模型,用来做类型校验:
from pydantic import BaseModel from fastapi import FastAPI, Request, Depends from typing import List class Product(BaseModel): id: str count: int # 自动将字符串转换为整数,还会做合法性校验 app = FastAPI()
然后写一个自定义依赖函数,专门解析这种方括号格式的参数:
def parse_php_style_products(request: Request) -> List[Product]: param_dict = dict(request.query_params) products_temp = {} # 遍历所有查询参数,解析键名中的索引和字段 for key, value in param_dict.items(): # 处理类似products[0][id]的键,拆分出索引和字段 key_parts = key.strip('[]').split('][') if len(key_parts) != 3 or key_parts[0] != "products": continue # 跳过非products前缀的参数 idx = key_parts[1] field = key_parts[2] # 按索引分组存储产品字段 if idx not in products_temp: products_temp[idx] = {} products_temp[idx][field] = value # 按索引排序,确保顺序正确,然后转换为Product模型列表 sorted_products = [products_temp[str(i)] for i in range(len(products_temp))] return [Product(**product_data) for product_data in sorted_products]
最后在接口中使用这个依赖:
@app.get("/api/") def get_products(products: List[Product] = Depends(parse_php_style_products)): print(products) # 输出示例:[Product(id='ABC123', count=1), Product(id='ABC124', count=2)] return {"products": products}
这个方案的优势:
- 自动做类型转换和校验(比如
count会从字符串转成整数,传非数字会直接返回422错误) - 即使参数顺序混乱(比如
products[1]的参数先出现),也能按索引正确排序 - 代码可复用,其他接口需要解析类似格式参数时直接用这个依赖就行
方案二:协调前端修改参数格式(更简洁)
如果可以协调前端改成FastAPI原生支持的嵌套参数格式(用点分隔),比如:
.../api/?products[0].id=ABC123&products[0].count=1&products[1].id=ABC124&products[1].count=2
那你只需要直接用Pydantic模型+List就能自动解析,不需要额外代码:
from pydantic import BaseModel from fastapi import FastAPI, Query from typing import List class Product(BaseModel): id: str count: int app = FastAPI() @app.get("/api/") def get_products(products: List[Product] = Query(None)): print(products) return {"products": products}
对比你之前的实现
你之前的循环按每两个参数取的方式有个明显缺陷:如果参数顺序不对、或者某个产品的字段缺失,就会导致解析结果错误。而上面的方案一通过按索引分组的方式,彻底避免了这个问题,同时还增加了类型校验,稳定性更高。
内容的提问来源于stack exchange,提问作者Filip Bartoš
相关产品推荐
相关产品推荐

