Django中实现自定义软删除Model的方法
本文介绍如何在Django中通过自定义Manager和QuerySet实现模型的软删除功能。通过重写delete方法,将记录标记为逻辑删除而非物理移除,从而支持数据恢复与统计。示例展示了SoftDeletableModel基类的构建及CustomerInfo模型的应用。
软删除概述
软删除
简单来说,软删除是指在执行删除操作时,并不真正从数据库中移除记录,而是通过逻辑标记的方式将其标记为已删除。这种做法的优势在于便于进行数据统计分析,同时也支持后续的数据恢复操作。
预备知识:Managers
预备知识
Managers
Manager是Django模型中用于提供数据库查询操作的接口。在Django应用程序中,每个模型至少包含一个Manager实例。
详细文档:https://docs.djangoproject.com/en/dev/topics/db/managers/
Django实现软删除Model
在Django中实现软删除Model
首先,
from django.db import models
from django.db.models.query import QuerySet
# 自定义软删除查询基类
class SoftDeletableQuerySetMixin(object):
"""
QuerySet for SoftDeletableModel. Instead of removing instance sets
its ``is_deleted`` field to True.
"""
def delete(self):
"""
Soft delete objects from queryset (set their ``is_deleted``
field to True)
"""
self.update(is_deleted=True)
class SoftDeletableQuerySet(SoftDeletableQuerySetMixin, QuerySet):
pass
class SoftDeletableManagerMixin(object):
"""
Manager that limits the queryset by default to show only not deleted
instances of model.
"""
_queryset_class = SoftDeletableQuerySet
def get_queryset(self):
"""
Return queryset limited to not deleted entries.
"""
kwargs = {'model': self.model, 'using': self._db}
if hasattr(self, '_hints'):
kwargs['hints'] = self._hints
return self._queryset_class(**kwargs).filter(is_deleted=False)
class SoftDeletableManager(SoftDeletableManagerMixin, models.Manager):
pass
其次,
# 自定义软删除抽象基类
class SoftDeletableModel(models.Model):
"""
An abstract base class model with a ``is_deleted`` field that
marks entries that are not going to be used anymore, but are
kept in db for any reason.
Default manager returns only not-deleted entries.
"""
is_deleted = models.BooleanField(default=False)
class Meta:
abstract = True
objects = SoftDeletableManager()
def delete(self, using=None, soft=True, *args, **kwargs):
"""
Soft delete object (set its ``is_deleted`` field to True).
Actually delete object if setting ``soft`` to False.
"""
if soft:
self.is_deleted = True
self.save(using=using)
else:
return super(SoftDeletableModel, self).delete(using=using, *args, **kwargs)
class CustomerInfo(SoftDeletableModel):
nid = models.AutoField(primary_key=True)
category = models.ForeignKey("CustomerCategory", to_field="nid", on_delete=models.CASCADE, verbose_name='客户分类',
db_constraint=False)
company = models.CharField(max_length=64, verbose_name="公司名称")
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









