pydantic_auto_field.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. from typing import Type, TypeVar, Dict, Any, Union, Optional
  2. from pydantic import BaseModel, model_validator
  3. # 定义一个通用类型变量,用于表示任意 Pydantic 模型
  4. ModelType = TypeVar("ModelType", bound=BaseModel)
  5. class ModelField:
  6. """
  7. 通用的字段类型,用于将字典自动转换为指定的 Pydantic 模型对象。
  8. """
  9. def __init__(self, model_class: Type[ModelType]):
  10. self.model_class = model_class
  11. def __call__(self, value: Any) -> ModelType:
  12. if isinstance(value, dict):
  13. return self.model_class(**value)
  14. elif isinstance(value, self.model_class):
  15. return value
  16. else:
  17. raise ValueError(f"Expected dict or {self.model_class}, got {type(value)}")
  18. class AutoLoadModel(BaseModel):
  19. """
  20. 基类,用于自动加载嵌套的 Pydantic 模型对象。
  21. """
  22. @model_validator(mode='before')
  23. def auto_load_nested_models(cls, values: Dict[str, Any]) -> Dict[str, Any]:
  24. for field_name, field in cls.model_fields.items():
  25. field_type = field.annotation
  26. if hasattr(field_type, "__origin__") and field_type.__origin__ is Union:
  27. # 处理 Union 类型(如 Optional)
  28. field_type = next(t for t in field_type.__args__ if t is not type(None))
  29. if isinstance(field_type, type) and issubclass(field_type, BaseModel):
  30. # 如果字段是 Pydantic 模型类型,则递归处理
  31. field_value = values.get(field_name)
  32. if isinstance(field_value, dict):
  33. values[field_name] = field_type(**field_value)
  34. elif isinstance(field_value, list):
  35. values[field_name] = [field_type(**item) if isinstance(item, dict) else item for item in field_value]
  36. elif isinstance(field_type, dict) and hasattr(field_type, "get") and callable(field_type.get):
  37. # 处理 Dict 类型,检查值是否为 Pydantic 模型
  38. field_value = values.get(field_name)
  39. if isinstance(field_value, dict):
  40. for key, value in field_value.items():
  41. if isinstance(value, dict):
  42. values[field_name][key] = field_type(value)
  43. return values