configuration.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import json
  2. from pydantic import BaseModel, model_validator
  3. from typing import Optional, Any
  4. from datetime import datetime
  5. class ConfigurationBase(BaseModel):
  6. config_key: Optional[str] = None
  7. config_value: Optional[str] = None
  8. description: Optional[str] = None
  9. type: Optional[str] = None
  10. class ConfigurationCreate(ConfigurationBase):
  11. config_key: str
  12. config_value: str
  13. class ConfigurationUpdate(ConfigurationBase):
  14. config_value: Optional[str] = None
  15. description: Optional[str] = None
  16. type: Optional[str] = None
  17. class ConfigurationOut(ConfigurationBase):
  18. id: int
  19. # 关键点 1: 必须覆盖 config_value 的类型注解为 Any,
  20. # 否则 Pydantic 会在输出时强行把它转换回字符串,或者报错
  21. config_value: Any
  22. model_config = {
  23. "from_attributes": True
  24. }
  25. @model_validator(mode='after')
  26. def parse_config_value_by_type(self) -> 'ConfigurationOut':
  27. """
  28. 根据 type 字段自动转换 config_value 的类型
  29. """
  30. if self.config_value is None or self.type is None:
  31. return self
  32. # 获取原始字符串值
  33. raw_value = str(self.config_value)
  34. target_type = self.type.lower()
  35. try:
  36. if target_type == 'int' or target_type == 'integer':
  37. self.config_value = int(raw_value)
  38. elif target_type == 'float':
  39. self.config_value = float(raw_value)
  40. elif target_type == 'bool' or target_type == 'boolean':
  41. # 处理 "true", "1", "yes" 等情况
  42. self.config_value = raw_value.lower() in ('true', '1', 'yes', 'on')
  43. elif target_type in ('json', 'list', 'dict', 'array', 'object'):
  44. # 尝试解析 JSON
  45. self.config_value = json.loads(raw_value)
  46. # 如果是 string 或其他未定义类型,保持原样
  47. except (ValueError, json.JSONDecodeError):
  48. # 如果转换失败(比如类型是 int 但值是 "abc"),
  49. # 这里选择保持原始字符串不报错,或者你可以选择抛出错误
  50. pass
  51. return self