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

223 lines
6.4 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.
# 删除规范
## 概述
统一使用软删除机制,通过 `is_delete` 字段标记记录状态,不物理删除数据。删除操作支持逗号分隔的多 ID 批量删除。
:::tip 软删除约定
- `is_delete = False`(0):正常记录(默认值)
- `is_delete = True`(1):已删除记录
- 所有查询方法自动过滤 `is_delete=False`,业务层无需关心
:::
## 软删除 vs 硬删除
| 维度 | 软删除 | 硬删除 |
|------|--------|--------|
| 实现方式 | 更新 `is_delete=True` | `DELETE FROM table` |
| 数据可恢复 | ✅ 可恢复 | ❌ 不可恢复 |
| 查询影响 | 需加 `is_delete=False` | 数据已不存在 |
| 存储空间 | 占用(数据仍在表中) | 释放 |
| 适用场景 | 业务数据(用户、订单等) | 日志、临时数据 |
| 项目约定 | ✅ 统一使用 | ❌ 禁止使用 |
## BaseModel 公共字段
所有业务模型继承 `BaseModel`,自动包含 `is_delete` 字段:
```python
# application/models.py
class BaseModel(models.Model):
"""基础模型类"""
class Meta:
abstract = True
id = models.AutoField(primary_key=True)
create_user = models.CharField(max_length=50, null=True, blank=True)
create_time = models.DateTimeField(auto_now_add=True)
update_user = models.CharField(max_length=50, null=True, blank=True)
update_time = models.DateTimeField(auto_now=True)
is_delete = models.IntegerField(default=0, db_comment='是否删除:0-正常 1-已删除')
```
## 删除接口
### URL 格式
```
DELETE /{module}/delete/{id}
```
支持逗号分隔的多 ID 删除:
```
DELETE /example/delete/1,2,3
```
### View 示例
```python
@method_decorator(check_login, name="delete")
class ExampleDeleteView(PermissionRequired, View):
"""删除案例视图"""
permission_required = ('sys:example:delete',)
@operation_log(title="案例管理-删除记录", log_type=LogType.DELETE)
def delete(self, request, id):
# 演示环境禁止操作
if DJANGO_DEMO:
return R.failed("演示环境,暂无操作权限")
result = services.delete_examples(id)
return result
```
## Service 实现
```python
def delete_examples(instance_ids):
"""删除案例(批量删除)"""
if not instance_ids:
return R.failed("记录ID不存在")
try:
# 解析ID列表
id_list = [int(id_str.strip()) for id_str in instance_ids.split(',') if id_str.strip()]
if not id_list:
return R.failed("无效的记录ID")
# 批量更新删除标识(逻辑删除)
updated_count = Example.objects.filter(
id__in=id_list,
is_delete=False
).update(is_delete=True)
return R.ok(msg=f"本次共删除{updated_count}条数据")
except ValueError:
return R.failed("记录ID格式错误")
except Exception as e:
logging.error(f"删除案例异常,IDs: {instance_ids}, 错误: {str(e)}")
return R.failed(msg="删除失败,请稍后重试")
```
:::tip 返回值说明
`delete` 方法返回实际软删除的条数。如果传入的 ID 中包含已删除或不存在的记录,返回值会小于入参数量。
:::
## 删除流程
```
1. View 接收请求(id 参数,逗号分隔)
↓
2. 演示模式检查(DJANGO_DEMO)
↓(拦截则返回 R.failed)
3. Service.delete_examples(id)
↓
4. 解析 ID 列表(逗号分隔转 list)
↓
5. ORM 批量更新 is_delete=True
↓
6. 返回 R.ok(msg="本次共删除N条数据")
```
## 查询过滤
所有查询方法必须过滤 `is_delete=False`:
```python
# 分页查询
query = Example.objects.filter(is_delete=False)
# 详情查询
instance = Example.objects.filter(is_delete=False, id=id).first()
# 列表查询
queryset = Example.objects.filter(is_delete=False, status=1)
# 带筛选条件的查询
query = Example.objects.filter(is_delete=False, name__contains=name)
```
:::warning 常见错误
忘记加 `is_delete=False` 是最常见的 bug,会导致已删除的数据重新出现在列表中。建议在代码审查时重点检查。
:::
## 级联删除处理
当模块之间存在关联关系时,删除父记录需要同步处理子记录:
```python
def delete_role(role_ids):
"""删除角色(同步清理关联数据)"""
id_list = [int(id_str.strip()) for id_str in role_ids.split(',')]
# 1. 软删除角色
updated_count = Role.objects.filter(
id__in=id_list, is_delete=False
).update(is_delete=True)
# 2. 同步软删除角色菜单关联
RoleMenu.objects.filter(
role_id__in=id_list, is_delete=False
).update(is_delete=True)
# 3. 同步软删除用户角色关联
UserRole.objects.filter(
role_id__in=id_list, is_delete=False
).update(is_delete=True)
return R.ok(msg=f"本次共删除{updated_count}条数据")
```
## 数据恢复
软删除的数据可以通过恢复接口重新启用:
```python
def restore_examples(instance_ids):
"""恢复已删除的案例"""
id_list = [int(id_str.strip()) for id_str in instance_ids.split(',')]
updated_count = Example.objects.filter(
id__in=id_list, is_delete=True
).update(is_delete=False)
return R.ok(msg=f"本次共恢复{updated_count}条数据")
```
:::tip 恢复场景
数据恢复通常用于:
1. 误删除后的数据恢复
2. 回收站功能
3. 数据审计
:::
## 权限标识
| 操作 | 权限标识 | 说明 |
|------|---------|------|
| 删除 | `sys:{module}:delete` | 删除记录(支持批量) |
## 常见错误提示
| 提示 | 原因 |
|------|------|
| "记录ID不存在" | 入参为空 |
| "无效的记录ID" | ID 格式错误或全部无效 |
| "记录ID格式错误" | ID 包含非数字字符 |
## 最佳实践
```
1. 统一软删除:所有业务数据使用 is_delete 字段,禁止物理删除
2. 查询过滤:所有查询加 is_delete=False,避免遗漏
3. 级联处理:删除父记录时同步处理关联的子记录
4. 批量删除:支持逗号分隔的多 ID,提高操作效率
5. 错误提示:返回明确的错误信息,便于排查
6. 操作日志:删除操作记录操作日志,便于审计
```
## 总结
删除规范统一使用软删除(`is_delete` 标记),支持逗号分隔的多 ID 批量删除。Service 层解析 ID 列表后通过 ORM 批量更新 `is_delete=True`。所有查询方法自动过滤 `is_delete=False`,业务层无需关心软删除逻辑。级联删除时需同步处理关联数据,保证数据一致性。