Files
DjangoAdmin_FastAPI_EleVue/shared/base_repository.py
T
ClaudeandClaude ae2e141713 refactor(repo): 收敛 base_model 双轨,删除函数统一走 repo.batch_delete_r
- shared/base_repository.py 新增 batch_delete_r(返回 R,等价原 base_model 语义)
- 20 个模块删除函数从 Model.batch_delete_r 改为 x_repo.batch_delete_r
- shared/base_model.py 移除 classmethod(get_by_id/get_by_ids/get_all_active/exists/batch_delete_r),只留字段 + to_dict
- 清理 base_model 多余 imports
- 实测 dept 删除、批量删除及多模块读接口正常

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-07 11:28:25 +08:00

171 lines
5.9 KiB
Python
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.
# +======================================================================
# | DjangoAdmin 企业数字化开发平台 [ 赋能开发者,助力企业发展 ]
# +----------------------------------------------------------------------
# | Copyright (c) 2021-2026 一米阳光团队 版权所有
# | 开源协议: Apache-2.0
# +======================================================================
"""通用 Repository 基类:封装各模型的数据访问层公共操作。
各模块 repository.py 继承本类并提供自定义查询,service 通过 repository 访问数据库。
"""
from typing import Generic, Optional, TypeVar
from core import R
from core.database import get_db_session
from shared.constants import PAGE_SIZE
from utils.request import parse_id_list
M = TypeVar("M")
class BaseRepository(Generic[M]):
"""模型数据访问基类。"""
# 软删除列名,JobLogRepository 覆盖为 "del_flag"
soft_delete_col: str = "is_delete"
def __init__(self, model_cls):
self.model = model_cls
@property
def db(self):
"""当前请求的数据库会话。"""
return get_db_session()
def _soft_col(self):
return getattr(self.model, self.soft_delete_col)
# ============================================================
# 基础查询
# ============================================================
def get_by_id(self, obj_id: Optional[int]) -> Optional[M]:
"""根据ID获取未删除记录(兼容字符串ID,如 URL 路径参数)。"""
if obj_id is None or obj_id == '':
return None
try:
obj_id = int(obj_id)
except (TypeError, ValueError):
return None
if obj_id <= 0:
return None
return self.db.query(self.model).filter(
self.model.id == obj_id, self._soft_col() == 0
).first()
def get_by_ids(self, ids) -> list:
"""根据ID列表批量获取未删除记录。"""
valid = []
for i in ids:
try:
i = int(i)
except (TypeError, ValueError):
continue
if i > 0:
valid.append(i)
if not valid:
return []
return self.db.query(self.model).filter(
self.model.id.in_(valid), self._soft_col() == 0
).all()
def get_all_active(self) -> list:
"""获取所有未删除记录。"""
return self.db.query(self.model).filter(self._soft_col() == 0).all()
def exists(self, obj_id: Optional[int]) -> bool:
"""检查未删除记录是否存在。"""
return self.get_by_id(obj_id) is not None
# ============================================================
# 分页查询
# ============================================================
def paginate(self, page_no: int = 1, page_size: int = PAGE_SIZE, query=None):
"""
分页查询,返回 (items, total)。自动追加软删过滤。
传入 query 可在外部先构建过滤条件。
"""
q = query if query is not None else self.db.query(self.model)
q = q.filter(self._soft_col() == 0)
total = q.count()
items = q.limit(page_size).offset((page_no - 1) * page_size).all()
return items, total
# ============================================================
# 写操作
# ============================================================
def create(self, **fields) -> M:
"""创建记录(不提交事务,由中间件统一管理)。"""
obj = self.model(**fields)
obj.save()
return obj
def update(self, obj_id, data: dict) -> int:
"""按ID更新,返回受影响行数。"""
return self.db.query(self.model).filter(
self.model.id == obj_id, self._soft_col() == 0
).update(data)
def soft_delete(self, ids) -> bool:
"""
批量软删除(等价 base_model.batch_delete_r 的语义)。
Args:
ids: 逗号分隔字符串或整数列表
Returns:
bool: 是否全部删除成功(ID 数需与匹配记录数一致)
"""
id_list = parse_id_list(ids) if isinstance(ids, str) else [i for i in ids if i]
if not id_list:
return False
records = self.db.query(self.model).filter(
self.model.id.in_(id_list), self._soft_col() == 0
).all()
if len(records) != len(id_list):
return False
for record in records:
setattr(record, self.soft_delete_col, 1)
return True
def batch_delete_r(self, ids_str) -> R:
"""
批量软删除并返回 R 对象(等价原 base_model.batch_delete_r)。
Args:
ids_str: 逗号分隔的ID字符串,如 "1,2,3"
Returns:
R: 操作结果(成功 code=0,失败 code=1)
"""
if not ids_str:
return R.failed("记录ID不存在")
id_list = parse_id_list(ids_str)
if not id_list:
return R.failed("记录ID不存在")
records = self.db.query(self.model).filter(
self.model.id.in_(id_list), self._soft_col() == 0).all()
if len(records) != len(id_list):
return R.failed("记录不存在")
for record in records:
setattr(record, self.soft_delete_col, 1)
return R.ok(msg="本次共删除{0}条数据".format(len(records)))
def hard_delete(self, obj) -> bool:
"""物理删除实例。"""
self.db.delete(obj)
self.db.flush()
return True
# ============================================================
# 自定义查询出口
# ============================================================
def filter(self, *criterion):
"""返回过滤后的 query,供子类组合复杂查询。"""
return self.db.query(self.model).filter(*criterion)