Django如何实现软删除功能替换原有硬删除逻辑
Django 软删除功能实现方案
软删除的核心逻辑是不实际物理删除数据库中的记录,通过专门的状态字段标记数据为已删除状态,查询时默认过滤掉标记为已删除的内容即可。
1. 修改模型层,添加软删除标记字段
首先给你的EmpModel新增软删除标识字段,如果你需要记录删除时间可以额外加时间字段:
from django.db import models class EmpModel(models.Model): # 保留你原有定义的所有字段,仅新增以下字段 is_deleted = models.BooleanField(default=False, verbose_name="是否已删除") # 可选:记录删除时间,不需要可以不加 # deleted_at = models.DateTimeField(null=True, blank=True, verbose_name="删除时间")
修改完模型后,在项目目录执行以下命令同步数据库结构:python manage.py makemigrationspython manage.py migrate
2. 修改删除视图逻辑,替换硬删除为软删除
你原有代码中调用的delete()是Django默认的物理删除方法,会直接把数据从数据库中移除,替换为修改软删除标记的逻辑即可:
from django.shortcuts import render, get_object_or_404 from .models import EmpModel # 如果加了deleted_at字段需要导入timezone # from django.utils import timezone def Delemp(request, id): # 用get_object_or_404替代直接get,id不存在时自动返回404响应,更鲁棒 delemployee = get_object_or_404(EmpModel, id=id) # 注释原硬删除逻辑 # delemployee.delete() # 执行软删除标记 delemployee.is_deleted = True # 如果加了deleted_at字段,补充记录删除时间 # delemployee.deleted_at = timezone.now() delemployee.save() # 查询时排除已标记软删除的数据 showdata = EmpModel.objects.filter(is_deleted=False) return render(request, "Index.html", {"data": showdata})
如果后续需要实现删除恢复功能,只需要把对应记录的is_deleted改回False保存即可。
3. 优化:自定义查询管理器,减少重复过滤代码
如果项目中多处需要查询员工数据,每次手动写filter(is_deleted=False)容易遗漏,可以自定义模型管理器,让默认查询自动过滤已删除数据:
在models.py中添加自定义管理器并注册到模型:
class SoftDeleteManager(models.Manager): # 默认查询仅返回未删除的数据 def get_queryset(self): return super().get_queryset().filter(is_deleted=False) # 提供方法查询所有数据(包含已软删除的记录) def all_with_deleted(self): return super().get_queryset() # 提供方法仅查询已软删除的记录 def deleted_only(self): return super().get_queryset().filter(is_deleted=True) class EmpModel(models.Model): # 原有字段、is_deleted字段保持不变 # ... # 注册自定义管理器 objects = SoftDeleteManager() # 保留原生管理器作为兜底,避免迁移等场景异常 origin_objects = models.Manager()
注册完成后,你在任何地方写EmpModel.objects.all()都会自动过滤已软删除的数据,不需要重复加过滤条件,和你原有代码的兼容性更好。需要查询包含已删除的全量数据时,调用EmpModel.objects.all_with_deleted()即可。
内容的提问来源于stack exchange,提问作者Ameya Potdar
相关产品推荐
相关产品推荐

