Skip to content

删除规范

概述

统一使用软删除机制,通过 is_delete 字段标记记录状态,不物理删除数据。删除操作支持逗号分隔的多 ID 批量删除。

软删除约定

  • is_delete = False(0):正常记录(默认值)
  • is_delete = True(1):已删除记录
  • 所有查询方法自动过滤 is_delete=False,业务层无需关心

软删除 vs 硬删除

维度软删除硬删除
实现方式更新 is_delete=TrueDELETE 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="删除失败,请稍后重试")

返回值说明

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)

常见错误

忘记加 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}条数据")

恢复场景

数据恢复通常用于:

  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,业务层无需关心软删除逻辑。级联删除时需同步处理关联数据,保证数据一致性。

小蚂蚁云团队 · 提供技术支持