如何通过独立父类在Pydantic中统一组织验证逻辑?代码失效求助
问题原因与修复方案
你的代码失效的核心原因是:Pydantic的@validator装饰器需要依附于Pydantic的元类系统才能生效,直接让模型继承普通类OrderValidator时,类中的验证器不会被Pydantic识别和注册。此外代码中还有几处逻辑错误需要修正。
具体修复步骤
让验证类继承BaseModel
将OrderValidator改为继承BaseModel,这样Pydantic才能正确处理其中的验证器装饰器。修正查询对象的笔误
第一个验证器product_exists中,你查询的是Order对象,但实际应该查询Product,否则逻辑完全错误。处理可选字段的边界情况
在EditOrder中product_id和product_quantity是可选字段,需要在check_quantity中先判断product_id是否存在,避免出现KeyError,同时只有当product_quantity有值时才执行验证。
修改后的完整代码
from typing import Optional from pydantic import BaseModel, validator # 假设你已经导入了create_session、Product、Order等依赖 class OrderValidator(BaseModel): @validator("product_id") def product_exists(cls, product_id): session = create_session() # 修正:查询Product而非Order product = session.query(Product).get(product_id) if product is None: raise ValueError(f"Product with the ID: {product_id} is not found") return product_id @validator("product_quantity") def check_quantity(cls, product_quantity, values): # 处理可选字段情况:只有product_id存在且product_quantity有值时才验证 product_id = values.get("product_id") if product_quantity is None or product_id is None: return product_quantity session = create_session() product = session.query(Product).get(product_id) if product.quantity < product_quantity: raise ValueError( f"This product does not have such a quantity: {product_quantity}" ) return product_quantity class CreateOrder(OrderValidator): product_id: int product_quantity: int contact_whatsapp: str contact_telegram: str contact_phone: str contact_name: str contact_city: str status = 0 class EditOrder(OrderValidator): product_id: Optional[int] product_quantity: Optional[int] contact_whatsapp: Optional[str] contact_telegram: Optional[str] contact_phone: Optional[str] contact_name: Optional[str] contact_city: Optional[str] status: Optional[int]
额外说明
- 当模型继承
OrderValidator后,OrderValidator中的字段会被继承,但这里OrderValidator没有定义任何字段,仅提供验证逻辑,所以不会影响子类的字段定义。 - 如果你使用的是Pydantic V2,建议使用
@field_validator替代@validator(V2中@validator已被标记为过时),用法类似:from pydantic import field_validator @field_validator("product_id") def product_exists(cls, product_id): # 验证逻辑不变
内容的提问来源于stack exchange,提问作者SkyGuy
相关产品推荐
相关产品推荐

