Files
djangoadmin-wiki/DjangoAdmin_Flask_EleVue/zh/volume2/model.md
T
2026-09-13 20:29:19 +08:00

216 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 数据模型(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 统一处理驼峰转换和字段过滤,子类无需重复定义。