0

0

在Django中实现软删除的全面指南

DDD

DDD

发布时间:2025-09-13 12:10:00

|

929人浏览过

|

来源于php中文网

原创

在Django中实现软删除的全面指南

本教程详细介绍了如何在Django应用中实现软删除功能,以替代默认的硬删除。文章首先阐述了Django默认删除行为的局限性,然后提供了两种实现软删除的主要策略:手动添加删除标志字段并定制管理器,以及推荐使用django-safedelete第三方库。通过具体的代码示例和最佳实践,帮助开发者高效、安全地管理数据生命周期,确保数据可恢复性和业务逻辑的完整性。

1. 理解Django的默认删除行为

在django orm中,当您调用模型实例的delete()方法时,默认执行的是硬删除(hard delete)。这意味着数据将从数据库中永久移除,无法恢复。这对于某些业务场景可能是不可接受的,例如,用户数据、订单记录或任何需要审计或日后恢复的信息。

考虑以下一个典型的Django视图函数,它演示了硬删除:

# views.py
from django.shortcuts import render, redirect, get_object_or_404
from .models import EmpModel

def Delemp(request, id):
    """
    此函数执行硬删除操作。
    """
    # 尝试获取指定ID的员工记录,如果不存在则返回404
    delemployee = get_object_or_404(EmpModel, id=id)
    # 执行硬删除,数据将从数据库中永久移除
    delemployee.delete()

    # 删除后重新获取所有未删除的员工数据(如果模型没有特殊处理,仍会包含已删除的)
    # 注意:这里假设EmpModel.objects.all()会返回所有当前存在的记录
    showdata = EmpModel.objects.all()
    return render(request, "Index.html", {"data": showdata})

在上述代码中,delemployee.delete()会直接发出DELETE SQL语句,将记录从数据库表中删除。

2. 软删除的必要性与实现策略

软删除(Soft Delete)是一种数据管理策略,它不是真正地从数据库中删除记录,而是通过标记记录为“已删除”来逻辑上隐藏它。这样,数据仍然保留在数据库中,可以在需要时恢复或进行审计。

实现软删除主要有两种策略:

  • 手动实现:通过在模型中添加一个布尔字段或日期时间字段来标记记录的删除状态,并定制模型管理器来过滤已删除的记录。
  • 使用第三方库:利用成熟的第三方库(如django-safedelete),它们提供了更完善、更便捷的软删除解决方案。

2.1 策略一:手动实现软删除

这种方法涉及修改您的模型定义,添加一个用于标记删除状态的字段,并创建自定义管理器来处理查询。

1. 修改模型 (models.py)

在您的模型中添加一个is_deleted布尔字段,并创建一个自定义管理器来默认排除已删除的记录。

# models.py
from django.db import models

class SoftDeleteManager(models.Manager):
    """
    自定义管理器,默认只返回未被软删除的对象。
    """
    def get_queryset(self):
        return super().get_queryset().filter(is_deleted=False)

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()

    class Meta:
        verbose_name = "员工"
        verbose_name_plural = "员工"

    def __str__(self):
        return self.name

    def soft_delete(self):
        """
        执行软删除操作。
        """
        if not self.is_deleted:
            self.is_deleted = True
            from django.utils import timezone
            self.deleted_at = timezone.now()
            self.save()

    def restore(self):
        """
        恢复已软删除的对象。
        """
        if self.is_deleted:
            self.is_deleted = False
            self.deleted_at = None
            self.save()

2. 修改视图函数 (views.py)

现在,您的视图函数将调用模型实例的soft_delete方法,而不是默认的delete()。

# views.py
from django.shortcuts import render, redirect, get_object_or_404
from .models import EmpModel

def Delemp(request, id):
    """
    此函数执行软删除操作。
    """
    employee = get_object_or_404(EmpModel, id=id)
    # 调用自定义的soft_delete方法
    employee.soft_delete()

    # 由于EmpModel.objects是SoftDeleteManager,它只会返回未删除的记录
    showdata = EmpModel.objects.all()
    return render(request, "Index.html", {"data": showdata})

注意事项:

  • 需要运行makemigrations和migrate来更新数据库模式。
  • 当您使用EmpModel.objects.all()或EmpModel.objects.filter(...)时,默认只会查询到is_deleted=False的记录。
  • 如果您需要查询所有记录(包括已删除的),可以使用EmpModel.all_objects.all()。
  • 这种手动实现方式需要您在所有相关查询中都使用正确的管理器,并确保外键关联的处理(例如,on_delete=models.DO_NOTHING 或自定义处理)。

2.2 策略二:使用 django-safedelete (推荐)

django-safedelete是一个功能强大且易于使用的第三方库,它为Django模型提供了软删除功能,并支持多种删除策略。

TURF(开源)权限管理系统
TURF(开源)权限管理系统

TURF(开源)权限定制管理系统(以下简称“TURF系统”),是蓝水工作室推出的一套基于软件边界设计理念研发的具有可定制性的权限管理系统。TURF系统充分考虑了易用性,将配置、设定等操作进行了图形化设计,完全在web界面实现,程序员只需在所要控制的程序中简单调用一个函数,即可实现严格的程序权限管控,管控力度除可达到文件级别外,还可达到代码级别,即可精确控制到

下载

1. 安装与配置

首先,使用pip安装django-safedelete:

pip install django-safedelete

然后,将其添加到您的Django项目的INSTALLED_APPS中:

# settings.py
INSTALLED_APPS = [
    # ... 其他应用
    'safedelete',
    # ... 您的应用
]

2. 修改模型 (models.py)

让您的模型继承自SafeDeleteModel,并定义一个删除策略。

# models.py
from django.db import models
from safedelete.models import SafeDeleteModel, SOFT_DELETE_POLICY, HARD_DELETE_POLICY, NO_DELETE_POLICY

class EmpModel(SafeDeleteModel):
    # 定义软删除策略
    # SOFT_DELETE_POLICY: 默认策略,将对象标记为已删除,保留在数据库中。
    # HARD_DELETE_POLICY: 即使继承了SafeDeleteModel,调用delete()也会执行硬删除。
    # NO_DELETE_POLICY: 禁止删除操作。
    _safedelete_policy = SOFT_DELETE_POLICY 

    name = models.CharField(max_length=100)
    email = models.EmailField(unique=True)

    class Meta:
        verbose_name = "员工"
        verbose_name_plural = "员工"

    def __str__(self):
        return self.name

3. 修改视图函数 (views.py)

使用django-safedelete后,您通常不需要改变调用delete()的方式,库会自动将其转换为软删除。

# views.py
from django.shortcuts import render, redirect, get_object_or_404
from .models import EmpModel

def Delemp(request, id):
    """
    此函数在django-safedelete的帮助下执行软删除操作。
    """
    employee = get_object_or_404(EmpModel, id=id)
    # 调用delete()方法,由于EmpModel继承自SafeDeleteModel且策略为SOFT_DELETE_POLICY,
    # 这将自动执行软删除,而不是硬删除。
    employee.delete()

    # SafeDeleteModel会自动调整其默认管理器,使其只返回未删除的记录。
    showdata = EmpModel.objects.all()
    return render(request, "Index.html", {"data": showdata})

django-safedelete 的高级用法:

  • 恢复对象: employee.undelete()
  • 强制硬删除: employee.hard_delete()
  • 查询所有对象 (包括已删除的): EmpModel.all_objects.all()
  • 查询已删除对象: EmpModel.deleted_objects.all()
  • 查询未删除对象: EmpModel.objects.all() (默认行为)
  • 自定义删除策略: 可以为不同的模型设置不同的_safedelete_policy。

3. 软删除的注意事项与最佳实践

  • 数据一致性:软删除不会自动处理外键约束。如果一个对象被软删除,但其关联对象仍然存在并指向它,可能会导致数据不一致。django-safedelete提供了一些选项来处理级联删除(例如,CASCADE、SET_NULL等),但您需要仔细规划。
  • 唯一性约束:如果您的模型字段有unique=True约束,软删除的对象仍然占据该唯一值。这意味着您不能创建具有相同唯一值的新对象,除非您在模型中自定义处理或使用django-safedelete的_safedelete_unique_fields属性。
  • 性能考量:虽然软删除提供了数据恢复的便利,但它会在数据库中保留更多数据,可能会影响查询性能,尤其是在处理大量软删除记录时。定期清理或归档旧的软删除记录可能是一个好习惯。
  • 用户界面:在前端展示数据时,需要确保您的查询只显示未被软删除的记录,或者根据业务需求显示已删除的记录并提供恢复选项。
  • API设计:如果您的应用提供API,请确保API端点能够正确处理软删除状态,例如,GET请求默认不返回已删除数据,或者提供一个参数来包含已删除数据。

总结

软删除是现代Web应用中一项重要的功能,它为数据管理提供了灵活性和安全性。虽然手动实现可以满足基本需求,但django-safedelete等第三方库提供了更全面、更易于维护的解决方案,强烈推荐在生产环境中使用。通过理解其工作原理并遵循最佳实践,您可以有效地在Django项目中实现和管理软删除功能。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

675

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

319

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

346

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1084

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

356

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

674

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

566

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

409

2024.04.29

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

74

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.7万人学习

AngularJS教程
AngularJS教程

共24课时 | 2.2万人学习

CSS教程
CSS教程

共754课时 | 17.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号