# 数据模型(Model) 数据模型是模块开发的第一步,用于定义数据库表结构。项目使用 `SQLAlchemy ORM`,模型类通过继承基类自动获得通用字段和方法。 ## 文件位置 ``` src/modules/system/position/models.py ``` ## 完整代码 以下为 `src/modules/system/position/models.py` 的核心代码(省略版权头): ```python """ 岗位模型模块 ============================================================= 提供岗位管理的数据模型定义,用于定义员工岗位信息。 企业级特性: 1. 使用枚举类管理状态常量,确保类型安全 2. 状态文本自动转换,便于前端展示 3. 便捷的查询方法,提高开发效率 4. 继承 BaseModel 和 BaseDB,复用通用功能 5. __init__ 由 BaseModel 统一管理,无需重复定义 """ from enum import IntEnum from typing import Optional, List from src.common.base_db import BaseDB from src.common.base_model import BaseModel from config import DB_PREFIX from sqlalchemy import text from src.core.database import db from src.common.utils.request import like_contains # ============================================================ # 岗位状态枚举 # ============================================================ class PositionStatus(IntEnum): """ 岗位状态枚举 使用 IntEnum 确保类型安全,避免魔法数字。 可直接用于数据库查询和比较。 """ DISABLED = 0 # 停用 ENABLED = 1 # 启用 # ============================================================ # 岗位模型 # ============================================================ class Position(BaseModel, BaseDB): """ 岗位模型 用于存储员工岗位信息,如:技术总监、产品经理等。 继承自 BaseModel(通用字段)和 BaseDB(数据库操作方法)。 """ # 表名:使用配置前缀 + 模型名 __tablename__ = DB_PREFIX + "position" __table_comment__ = "岗位表" # ============================================================ # 字段定义 # ============================================================ # 岗位名称:必填字段,最长255字符 name = db.Column( db.String(255), nullable=False, index=True, comment="岗位名称" ) # 岗位状态:使用枚举确保类型安全 # 默认值为停用,创建后需手动启用 status = db.Column( db.Integer, index=True, default=PositionStatus.DISABLED, server_default=text('0'), comment="岗位状态:0-停用 1-启用" ) # 岗位排序:数值越小越靠前 sort = db.Column( db.Integer, default=0, server_default=text('0'), comment="岗位排序" ) # ============================================================ # 注意:__init__ 方法在 BaseModel 中已实现,无需重复定义 # BaseModel 已处理驼峰转换、字段过滤等逻辑 # ============================================================ # ============================================================ # 便捷属性 # ============================================================ @property def status_text(self) -> str: """获取岗位状态文本:将数字状态转换为可读的中文文本""" status_map = { PositionStatus.DISABLED: '停用', PositionStatus.ENABLED: '启用' } return status_map.get(self.status, '未知') @property def is_enabled(self) -> bool: """判断岗位是否启用""" return self.status == PositionStatus.ENABLED @property def is_disabled(self) -> bool: """判断岗位是否停用""" return self.status == PositionStatus.DISABLED # ============================================================ # 自定义查询方法 # ============================================================ @classmethod def get_enabled(cls) -> List['Position']: """获取所有启用的岗位,按排序值升序排列""" return cls.query.filter( cls.is_delete == 0, cls.status == PositionStatus.ENABLED ).order_by(cls.sort.asc()).all() @classmethod def get_by_name(cls, name: Optional[str]) -> Optional['Position']: """根据岗位名称精确查询""" if not name: return None return cls.query.filter( cls.name == name, cls.is_delete == 0 ).first() def __repr__(self) -> str: return f'岗位:{self.name}' ``` ## 代码解析 ### 基类继承 ```python class Position(BaseModel, BaseDB): ``` | 基类 | 来源 | 提供能力 | |:----|:----|:----| | `BaseModel` | `src/common/base_model.py` | 通用字段:id、create_user、create_time、update_user、update_time、is_delete | | `BaseDB` | `src/common/base_db.py` | `save()` 持久化方法(仅 flush,不 commit)、`to_dict()` 序列化方法 | ### 状态枚举 项目推荐使用 `IntEnum` 管理状态常量,避免魔法数字: ```python class PositionStatus(IntEnum): DISABLED = 0 # 停用 ENABLED = 1 # 启用 ``` | 值 | 含义 | |:----|:----| | 0 | 停用 / 禁用 | | 1 | 启用 / 在用 | 软删除字段 `is_delete` 由基类提供:`0` = 正常,`1` = 已删除。 ### 字段定义风格 项目使用 `db.Column`(从 `src.core.database` 导入的 `db` 实例),而非直接导入 `Column`: ```python from src.core.database import db name = db.Column(db.String(255), nullable=False, index=True, comment="岗位名称") ``` ### 表名配置 ```python __tablename__ = DB_PREFIX + "position" ``` `DB_PREFIX` 从 `.env` 读取(默认 `flask_`),最终表名为 `flask_position`。 ## 开发要点 1. **业务字段仅定义差异部分**:通用字段(id、时间、软删除等)由基类自动提供 2. **表名必须加 `DB_PREFIX` 前缀**:保持命名一致性 3. **使用 `db.Column` 而非直接导入 `Column`**:保持与项目一致的导入风格 4. **状态字段使用 IntEnum**:避免魔法数字,提高代码可读性 5. **同时设置 `default` 和 `server_default`**:确保 ORM 和直 SQL 两种场景都能正确赋默认值 6. **`__init__` 由 BaseModel 统一管理**:无需在子类中重复定义 ## 总结 数据模型继承 `BaseModel`(公共字段)和 `BaseDB`(save 方法),表名必须加 `DB_PREFIX` 前缀。状态字段使用 `IntEnum` 枚举类管理,字段定义使用 `db.Column` 风格。`__init__` 由 BaseModel 统一处理驼峰转换和字段过滤,子类无需重复定义。