
在数据管理中,删除操作通常分为硬删除(hard delete)和软删除(soft delete)。硬删除是指将数据从数据库中永久移除,一旦删除,数据便不可恢复。而软删除则不同,它不会真正从数据库中删除数据,而是通过标记(例如,设置一个布尔字段或时间戳字段)来表示该数据已“逻辑删除”或“失效”。这样做的好处包括:
Django ORM的delete()方法默认执行的是硬删除。当我们在视图函数中调用Model.objects.get(id=id).delete()时,对应的数据库记录将被永久移除。例如,以下代码片段展示了典型的硬删除操作:
# models.py
from django.db import models
class EmpModel(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField(unique=True)
# ... 其他字段
def __str__(self):
return self.name
# views.py (原始硬删除示例)
from django.shortcuts import render, redirect
from .models import EmpModel
def Delemp(request, id):
"""
此函数执行硬删除操作,将指定ID的员工记录从数据库中永久移除。
"""
try:
employee = EmpModel.objects.get(id=id)
employee.delete() # 执行硬删除
# 删除成功后,通常会重定向或刷新数据列表
showdata = EmpModel.objects.all()
return render(request, "Index.html", {"data": showdata})
except EmpModel.DoesNotExist:
# 处理记录不存在的情况
return redirect('some_error_page') # 或者返回一个错误信息要将上述硬删除逻辑转换为软删除,我们需要改变delete()方法的行为或引入额外的字段来标记数据状态。
在Django中实现软删除主要有两种策略:手动实现和利用第三方库。
手动实现软删除需要修改模型定义,并可能需要自定义管理器或重写delete()方法。
1. 修改模型定义
在需要支持软删除的模型中添加一个布尔字段(例如is_deleted)或一个时间戳字段(例如deleted_at)。
# models.py
from django.db import models
from django.utils import timezone
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):
name = models.CharField(max_length=100)
email = models.EmailField(unique=True)
is_deleted = models.BooleanField(default=False) # 软删除标记
deleted_at = models.DateTimeField(null=True, blank=True) # 删除时间戳(可选)
objects = SoftDeleteManager() # 使用自定义管理器
all_objects = models.Manager() # 保留默认管理器以访问所有记录
def delete(self, *args, **kwargs):
"""
重写delete方法,执行软删除。
"""
self.is_deleted = True
self.deleted_at = timezone.now() # 记录删除时间
self.save()
def hard_delete(self, *args, **kwargs):
"""
提供一个硬删除的方法,以防需要彻底删除。
"""
super().delete(*args, **kwargs)
def restore(self):
"""
恢复软删除的记录。
"""
self.is_deleted = False
self.deleted_at = None
self.save()
def __str__(self):
return self.name2. 更新视图函数
现在,Delemp函数将执行软删除:
# views.py
from django.shortcuts import render, redirect
from .models import EmpModel
def Delemp(request, id):
"""
此函数执行软删除操作。
"""
try:
employee = EmpModel.objects.get(id=id)
employee.delete() # 调用重写的delete方法,执行软删除
# 刷新数据列表,SoftDeleteManager会自动过滤掉已删除的
showdata = EmpModel.objects.all()
return render(request, "Index.html", {"data": showdata})
except EmpModel.DoesNotExist:
return redirect('some_error_page')
# 如果需要显示所有(包括已删除)的员工
def ShowAllEmp(request):
all_employees = EmpModel.all_objects.all_with_deleted()
return render(request, "AllEmployees.html", {"data": all_employees})
# 如果需要恢复某个员工
def RestoreEmp(request, id):
try:
employee = EmpModel.all_objects.get(id=id) # 使用all_objects来获取已删除的记录
employee.restore()
return redirect('index_page')
except EmpModel.DoesNotExist:
return redirect('some_error_page')手动实现注意事项:
django-safedelete是一个功能强大且易于使用的第三方库,专门用于在Django中实现软删除。它提供了灵活的策略控制,并能自动处理管理器和查询过滤。
1. 安装 django-safedelete
pip install django-safedelete
2. 配置 settings.py
将safedelete添加到INSTALLED_APPS中:
# settings.py
INSTALLED_APPS = [
# ...
'safedelete',
# ...
]3. 修改模型定义
在需要软删除的模型中继承SafeDeleteMixin,并定义_safedelete_policy。
# models.py
from django.db import models
from safedelete.models import SafeDeleteModel, SOFT_DELETE_CASCADE
class EmpModel(SafeDeleteModel):
# _safedelete_policy 定义删除策略
# SOFT_DELETE_CASCADE: 软删除时,级联软删除相关联的对象
# HARD_DELETE: 硬删除 (默认)
# NO_DELETE: 不允许删除
# SOFT_DELETE_NOCASCADE: 软删除,但不级联
_safedelete_policy = SOFT_DELETE_CASCADE
name = models.CharField(max_length=100)
email = models.EmailField(unique=True)
# SafeDeleteModel 会自动添加 deleted 字段和相关管理器
def __str__(self):
return self.name4. 运行数据库迁移
python manage.py makemigrations python manage.py migrate
django-safedelete会自动为模型添加一个deleted字段,并修改其管理器。
5. 更新视图函数
使用django-safedelete后,delete()方法会自动执行软删除。
# views.py
from django.shortcuts import render, redirect
from .models import EmpModel
from safedelete.models import DELETED_VISIBLE_BY_PK # 用于通过主键查询已删除对象
def Delemp(request, id):
"""
此函数执行软删除操作(由django-safedelete处理)。
"""
try:
employee = EmpModel.objects.get(id=id)
employee.delete() # 调用delete(),django-safedelete会自动执行软删除
# 默认情况下,EmpModel.objects.all() 不会包含已删除的记录
showdata = EmpModel.objects.all()
return render(request, "Index.html", {"data": showdata})
except EmpModel.DoesNotExist:
return redirect('some_error_page')
# 查询所有记录(包括已删除的)
def ShowAllEmp(request):
# 使用all_objects管理器来获取所有记录,包括已删除的
all_employees = EmpModel.all_objects.all()
return render(request, "AllEmployees.html", {"data": all_employees})
# 查询已删除的记录
def ShowDeletedEmp(request):
deleted_employees = EmpModel.deleted_objects.all()
return render(request, "DeletedEmployees.html", {"data": deleted_employees})
# 恢复软删除的记录
def RestoreEmp(request, id):
try:
# 使用all_objects来获取可能已被软删除的记录
employee = EmpModel.all_objects.get(id=id)
employee.undelete() # django-safedelete提供的恢复方法
return redirect('index_page')
except EmpModel.DoesNotExist:
return redirect('some_error_page')
# 彻底硬删除记录(需要谨慎使用)
def HardDeleteEmp(request, id):
try:
employee = EmpModel.all_objects.get(id=id)
employee.hard_delete() # django-safedelete提供的硬删除方法
return redirect('index_page')
except EmpModel.DoesNotExist:
return redirect('some_error_page')django-safedelete的优势:
在Django项目中实现软删除是管理数据生命周期、提升系统健壮性的重要实践。无论是通过自定义模型和管理器进行手动实现,还是借助django-safedelete等成熟的第三方库,理解其背后的原理和权衡是至关重要的。对于大多数场景,推荐使用django-safedelete,因为它能以最少的代码量提供强大而灵活的软删除功能,显著提高开发效率和代码质量。通过选择合适的策略并注意相关事项,开发者可以有效地在Django应用中构建健壮的数据删除机制。
以上就是在Django中实现软删除:策略与实践的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号