一个简单的django应用程序,为所需的模型添加软删除功能

django-softdelete-it的Python项目详细描述


向所需模型添加软删除功能。

快速启动

按照下面提到的步骤在任何django应用程序模型中添加soft-delete功能。

  1. pip install django-softdelete-it

  2. soft_delete_it添加到已安装的应用程序设置中,如下所示:

    INSTALLED_APPS = [
      ...
      'soft_delete_it',
     ]
    
  3. SoftDeleteModel从soft_delete_it app导入模型文件,如下所示:

    from soft_delete_it import SoftDeleteModel
    
  4. SoftDeleteModel类继承到模型类。它将添加以下功能:
    • objectsmanager的行为将发生变化,从而:
      • delete()方法,它将软删除实例
      • 始终只返回“非软删除”对象
      • hard_delete()`方法来硬删除对象
    • all_objects管理器:
      • 将始终返回软删除和非软删除对象
      • hard_delete()方法来硬删除对象
      • only_deleted()方法只返回软删除的对象
      • undelete()取消删除软删除对象的方法

示例

from django.db import models
from soft_delete_it.models import SoftDeleteModel


class Author(SoftDeleteModel):
    name = models.CharField(max_length=50)
    dob = models.DateField()


class Article(SoftDeleteModel):
    title = models.CharField(max_length=50)
    body = models.TextField(null=True)
    author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='articles')


Bob = Author.objects.create(name='bob', dob='2000-12-12')
John = Author.objects.create(name='john', dob='1990-10-12')

Author.objects.all() # return QuerySet with 2 objects
Bob.delete() # Bob is soft-deleted
Author.objects.all() # return QuerySet with 1 object, John
Author.all_objects.all() # return QuerySet with 2 object, Bob and John
Bob.undelete() # un-deletes Bob object
Author.objects.all() # return QuerySet with 2 objects


article1 = Article(title='Bob The Builder', body='')
article1.author = Bob
article1.save()

Article.objects.all() # return QuerySet with 1 object, article1

Bob.delete() # soft-deletes both Bob and article1 as Article's author field is on_delete_cascade and it Inherits SoftDeleteModel

如果要为模型实现一个新的Manager,只需与其他管理器一起继承SoftDeleteManager

如果要为模型实现新的QuerySet,则需要执行以下操作:
  1. 继承SoftDeleteQuerySet
  2. 写管理器继承SoftDeleteManager,它在其__init__()方法(如示例所示)中定义软删除功能,并重写get_queryset()方法(如示例所示)
  3. 编写继承SoftDeleteModel的模型类并使用上述新定义的Manager方法(如示例中所示)

queryset

的示例

允许为项目创建QuerySet,以便在创建新项目时如果未提供作者,则将在对象中添加一个默认作者。

#Creating a default author object first
default_author = Author.objects.create(name='default')

#Implementing QuerySet
from soft_delete_it.models import SoftDeleteModel, SoftDeleteQuerySet, SoftDeleteManager

class ArticleQuerySet(SoftDeleteQuerySet):

    def create(self, **kwargs):
        try:
            author = kwargs['author']
        except KeyError:
            kwargs['author'] = Author.objects.get(name='default')
        article = super(ArticleQuerySet, self).create(**kwargs)
        return article

class ArticleManager(SoftDeleteManager):

    def __init__(self, *args, **kwargs):
        self.deleted_also = kwargs.get('deleted_also', False)
        super(ArticleManager, self).__init__(*args, **kwargs)

    def get_queryset(self):
        '''return all unsoft-deleted objects'''
        if self.deleted_also:
            return ArticleQuerySet(self.model)
        return ArticleQuerySet(self.model).filter(deleted=None)

class Article(SoftDeleteModel):
    title = models.CharField(max_length=50)
    body = models.TextField(null=True)
    author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='articles')

    objects = ArticleManager.from_queryset(ArticleQuerySet)()
    all_objects = ArticleManager.from_queryset(ArticleQuerySet)(deleted_also=True)

如何实现软删除功能:

  1. 创建一个新的软删除应用程序,整个软删除功能的代码在其models.py文件中实现。
  2. 添加了一个抽象的SoftDeleteModel,其中包含一个deleted属性,即UUIDField。对于未删除的对象,它将保留None,对于已删除的对象,它将保留一个新的uuid4
  3. SoftDeleteQuerySet实现以将默认django的delete方法重写为soft-delete对象,而不是硬删除它们。
  4. undelete()hard_delete()only_deleted()方法在同一个QuerySet类中实现,以提供额外的功能。
  5. SoftDeleteManger通过重写get_queryset()方法实现以使用上面的queryset。
  6. queryset的delete方法必须重写才能支持bulk_delete功能。
  7. 在上述删除方法定义前后调用pre_delete和post_delete信号。
  8. 使用django管理实用程序中的nestedobjects软删除所有相关对象。
  9. 两个管理器,objectsall_objects返回undeleted,所有对象都实现了。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java如何将cassandra中的行数据转换为与列相关的嵌套json   java如何使用jcr XPath在jcr:content/@jcr:data中搜索?   java在使用openCV进行安卓开发时如何利用手机的广角镜头   java解析扩展了接口,结束了一个潜在的无限循环   位置服务的@Override方法中存在java Android应用程序错误   java本地线程的用途和需求是什么   具有左右子访问的java节点树遍历   java验证JsonWebToken签名   JUL日志处理程序中的java日志记录   嵌入式Java读取给定时间段的串行数据。   java有没有办法从多个URL获取多个图像?   java线程通过等待intent阻止自己发送intent   java Spring MVC解析多部分内容请求   java JPA/Hibernate静态元模型属性未填充NullPointerException   java格式错误的字符(需要引号,得到I)~正在处理   java为什么PrintWriter对象抛出FileNotFoundException?   java Neo4j未正确保存标签   java IE不加载图像