FastAPI中Pydantic validator校验组合模型触发AttributeError如何解决
问题根因
当你在FastAPI路由中指定response_model=SomeModel时,FastAPI的处理逻辑是:
- 拿到你返回的
SomeModel实例后,会先调用.dict()方法将其序列化为Python字典 - 再把这个字典传入
SomeModel的构造函数做二次校验,确保返回值符合response_model的定义
你的are_items_in_order校验器加了pre=True参数,会在Pydantic做字段类型解析之前就执行,所以此时拿到的other参数是字典类型,自然没有value属性,触发报错。
解决方法
下面提供三种可直接落地的方案,按需选择:
- 方案1:校验器兼容两种输入类型
直接在校验逻辑里判断输入是字典还是模型实例,分别取值即可,适合必须保留pre=True的场景:@validator('other', pre=True, always=True) def are_items_in_order(cls, other): cur_val = 0 # 兼容字典和实例两种输入 other_value = other['value'] if isinstance(other, dict) else other.value if cur_val > other_value: raise ValueError('out of order') return other - 方案2:移除
pre=True参数
如果你的校验逻辑不需要在类型解析之前执行,直接去掉pre=True即可,此时Pydantic会先把传入的字典解析为OtherModel实例,再执行校验逻辑,拿到的other永远是实例类型:@validator('other', always=True) def are_items_in_order(cls, other): cur_val = 0 if cur_val > other.value: raise ValueError('out of order') return other - 方案3:关闭FastAPI的response二次校验
如果你已经确保返回的实例一定符合格式要求,可以在路由装饰器中加response_model_validate=False(FastAPI 0.95+版本支持),跳过二次校验步骤,从根源避免二次触发校验的问题:@app.get("/test", response_model=SomeModel, response_model_validate=False) async def exec_test(): something = some_function() print(something) return something
内容的提问来源于stack exchange,提问作者Ryan Goss
相关产品推荐
相关产品推荐

