如何在FastAPI中实现基于所有字段的接口结果过滤?
问题分析与修复方案
报错原因
你遇到的TypeError是因为fetch_comments()返回的是评论对象组成的列表,不是单个字典,你却用了字典的索引方式result[x],自然会报错。另外你错误套用了ORM的query.filter逻辑,但这里是从第三方API获取的内存数据,并非数据库查询,这套逻辑完全不适用。
修复思路
要实现多条件可选过滤,核心是先收集有效的过滤参数,再遍历评论列表逐一匹配:
- 整理过滤参数:把路由中传入的非空参数打包成字典,避免处理无效的
None值 - 筛选评论:遍历每个评论,检查是否满足所有过滤条件(支持精确匹配或模糊匹配,按需选择)
- 返回筛选后的结果
修改后的代码
路由代码
from typing import Optional, List from fastapi import APIRouter # 替换成你的实际模块导入路径 from your_module import jsonplaceholder, Comments router = APIRouter() @router.get('/comments', summary="Fetch all comments", status_code=200, response_model=List[Comments], response_description="Returns comments data." ) def fetch_all_comments( postId: Optional[int] = None, # 第三方返回的postId是整数,改为int更合理 id: Optional[int] = None, name: Optional[str] = None, email: Optional[str] = None, body: Optional[str] = None ): # 获取第三方API返回的所有评论 all_comments = jsonplaceholder.fetch_comments() # 收集非空的过滤参数 filters = {} if postId is not None: filters['postId'] = postId if id is not None: filters['id'] = id if name is not None: filters['name'] = name if email is not None: filters['email'] = email if body is not None: filters['body'] = body # 无过滤参数时直接返回全部评论 if not filters: return all_comments # 筛选符合条件的评论 filtered_comments = [] for comment in all_comments: match = True for key, value in filters.items(): # 字符串类型支持不区分大小写的模糊匹配,要精确匹配就换成 == if isinstance(value, str): if value.lower() not in comment[key].lower(): match = False break # 数字类型做精确匹配 else: if comment[key] != value: match = False break if match: filtered_comments.append(comment) return filtered_comments
模型代码(建议调整)
第三方API返回的postId是整数类型,将模型中的对应字段类型修正,避免类型转换问题:
from pydantic import BaseModel class Comments(BaseModel): postId: int # 从str改为int id: int name: str email: str body: str
依赖代码(无需修改)
原fetch_comments()逻辑正常,保持原样即可:
import requests from your_module import ThirdPartyException # 替换成你的实际异常类路径 def fetch_comments(): req = requests.get( "https://jsonplaceholder.typicode.com/comments", verify=False) if req.status_code not in [200, 201]: raise ThirdPartyException( "Error", req.status_code, req.reason) response = req.json() return response
逻辑说明
- 过滤参数仅收集非空值,避免无效判断
- 字符串类型默认做不区分大小写的模糊匹配,如需精确匹配可将
in改为== - 无过滤参数时直接返回全部数据,减少不必要的遍历开销
内容的提问来源于stack exchange,提问作者fahmijaafar
相关产品推荐
相关产品推荐

