Files
djangoadmin-wiki/DjangoAdmin_Flask_AntdVue/zh/volume7/repository.md
T
2026-09-12 23:12:15 +08:00

113 lines
4.0 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.
# Repository 层规范
## 概述
Repository 层是数据访问层,封装所有数据库操作。各模块 Repository 继承 `BaseRepository`,获得通用 CRUD 能力,子类按需添加自定义查询。
:::tip 设计原则
- Repository 只做数据访问原语,不处理 R 封装/序列化/业务逻辑
- 所有方法均为 `@classmethod`,无需创建实例
- 软删除由基类自动处理,子类无需关心
- 查询方法自动跳过空值条件
:::
## 标准模块结构
```python
# src/modules/system/position/repository.py
from src.common.base_repository import BaseRepository
from src.common.constants.common import PAGE_SIZE
from src.modules.system.position.models import Position
class PositionRepository(BaseRepository):
"""岗位数据仓储"""
model = Position
@classmethod
def page(cls, params: dict):
"""岗位分页查询"""
return cls.find_page(
page=int(params.get('pageNo', 1)),
page_size=int(params.get('pageSize', PAGE_SIZE)),
filters={'status': params.get('status')},
like_filters={'name': params.get('name')},
order_by='sort',
)
@classmethod
def list_enabled(cls, params=None):
"""查询启用的岗位列表"""
params = params or {}
return cls.find_list(
filters={'status': 1},
like_filters={'name': params.get('name')},
order_by='sort',
)
```
## 必须实现的方法
| 方法 | 说明 | 何时需要 |
|:---|:---|:---|
| `page(params)` | 分页查询 | 所有模块(Service 的 `get_page` 依赖此方法) |
| `list_enabled(params)` | 无分页列表查询 | 需要下拉选择的模块(Service 的 `get_list` 依赖此方法) |
## BaseRepository 通用方法
| 方法 | 说明 | 自动过滤软删除 |
|:---|:---|:---|
| `get_by_id(obj_id)` | 按主键查询单条 | 是 |
| `get_by_ids(ids)` | 按主键列表批量查询 | 是 |
| `first_by(filters)` | 按等值条件查询单条 | 是 |
| `exists_by(filters, exclude_id)` | 检查是否存在(唯一性校验) | 是 |
| `count_by(filters)` | 按等值条件统计记录数 | 是 |
| `exists(obj_id)` | 检查记录是否存在 | 是 |
| `count_children(parent_id)` | 统计子记录数 | 是 |
| `find_page(...)` | 统一分页查询 | 是 |
| `find_list(...)` | 统一不分页查询 | 是 |
| `create(**kwargs)` | 创建并保存新实例 | - |
| `update_by_id(obj_id, data)` | 按主键更新字段 | - |
| `update_status(obj_id, status)` | 单独更新状态字段 | - |
| `delete_by_id(obj_id)` | 软删除单条记录 | - |
| `batch_delete(ids)` | 批量软删除 | - |
| `batch_restore(ids)` | 批量恢复已删除记录 | - |
## 使用示例
```python
# 唯一性校验
if PositionRepository.exists_by({'name': '高级工程师'}, exclude_id=5):
raise ValidationError('岗位名称已存在')
# 按 ID 查询
position = PositionRepository.get_by_id(1)
# 条件查询
user = UserRepository.first_by({'username': 'admin'})
# 统计引用
count = UserRepository.count_by({'position_id': 1})
# 分页查询
items, total, pages = PositionRepository.find_page(
page=1, page_size=10,
filters={'status': 1},
like_filters={'name': '工程师'},
order_by='sort',
)
```
## 开发要点
1. **所有方法均为 classmethod**:无需创建实例,直接通过类调用
2. **必须实现 `page(params)`**:Service 的 `get_page` 依赖此方法
3. **按需实现 `list_enabled(params)`**:需要下拉选择的模块实现此方法
4. **`find_page` / `find_list` 自动过滤软删除**:且跳过空值查询条件
5. **`exists_by(filters, exclude_id)` 用于唯一性校验**:支持排除自身 ID
6. **Repository 层不做响应封装**:返回 SQLAlchemy 查询结果
## 总结
Repository 层继承 `BaseRepository` 获得通用 CRUD 能力,所有方法均为 `classmethod`。子类只需声明 `model` 并实现 `page()` / `list_enabled()` 方法。`find_page` / `find_list` 自动过滤软删除且跳过空值条件,`exists_by` 用于唯一性校验。