如何为FastAPI的CRUDBase泛型类添加可选的ValidateSchemaType参数
解决方案
你写的泛型声明语法不生效,是因为Python的Generic不支持直接在方括号内为泛型参数设置默认值。以下是两种完全兼容现有子类的可行实现方案:
方案1:Python 3.11+ 原生泛型参数默认(类型提示最完善)
首先定义带默认值的泛型变量:
from typing import Generic, Optional, TypeVar from pydantic import BaseModel, ValidationError ModelType = TypeVar("ModelType") CreateSchemaType = TypeVar("CreateSchemaType", bound=BaseModel) UpdateSchemaType = TypeVar("UpdateSchemaType", bound=BaseModel) # 给验证泛型设置默认值为None ValidateSchemaType = TypeVar("ValidateSchemaType", bound=BaseModel, default=None)
改造CRUDBase基类:
class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType, ValidateSchemaType]): def __init__(self, model: type[ModelType]): self.model = model # 绑定泛型类型到实例变量,运行时可以直接读取 self.validate_schema: Optional[type[ValidateSchemaType]] = ValidateSchemaType def validate(self, db_obj: ModelType): if self.validate_schema is None: raise NotImplementedError try: self.validate_schema.from_orm(db_obj) except ValidationError as e: return translate_error(e) return {}
现有子类不需要做任何修改,新子类需要验证功能时,只要继承时指定第四个泛型参数即可:
class ItemValidateSchema(BaseModel): name: str price: float class Config: orm_mode = True class CRUDItem(CRUDBase[Item, ItemCreate, ItemUpdate, ItemValidateSchema]): # 不需要额外写其他代码,自动继承validate方法 pass
方案2:全版本兼容类变量实现(无Python版本限制)
如果你的项目Python版本低于3.11,用类变量配置验证Schema的方案完全无破坏性,不需要修改现有子类:
from typing import Generic, Optional, TypeVar from pydantic import BaseModel, ValidationError ModelType = TypeVar("ModelType") CreateSchemaType = TypeVar("CreateSchemaType", bound=BaseModel) UpdateSchemaType = TypeVar("UpdateSchemaType", bound=BaseModel) ValidateSchemaType = TypeVar("ValidateSchemaType", bound=BaseModel) class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]): # 基类默认设置为None,不需要验证的子类不用管这个变量 validate_schema: Optional[type[ValidateSchemaType]] = None def __init__(self, model: type[ModelType]): self.model = model def validate(self, db_obj: ModelType): if self.validate_schema is None: raise NotImplementedError try: self.validate_schema.from_orm(db_obj) except ValidationError as e: return translate_error(e) return {}
需要验证功能的子类只要给类变量赋值即可:
class CRUDItem(CRUDBase[Item, ItemCreate, ItemUpdate]): validate_schema = ItemValidateSchema
内容的提问来源于stack exchange,提问作者Egorrko
相关产品推荐
相关产品推荐

