之前使用TP
,框架自带有软删除功能,如果使用django
,虽然没有内置,我们也可以来简单的手写一下。想到这里权衡下,我们几乎所有的表都要用到这个字段甚至多个字段,当然我们可以不厌其烦的每个模型单独创建下,我们也可以使用代码复用的思想来完成这件事。
模型字段复用
需要复用的字段有:
1 2 3
| create_time = models.DateTimeField(verbose_name='添加时间', auto_now_add=True) update_time = models.DateTimeField(verbose_name='更新时间', auto_now=True) delete_time = models.DateTimeField(verbose_name='删除时间', null=True, blank=True)
|
模型类都有一个元属性,有一个关键字叫abstract
,如果将该属性设置为True
,数据库将不再创建该表。然而我们可以利用其来做父类,继承过来所有的模型不就自带这些字段了吗。
1 2 3 4 5 6 7 8 9 10 11 12
| class SoftDeleteModel(models.Model): create_time = models.DateTimeField(verbose_name='添加时间', auto_now_add=True) update_time = models.DateTimeField(verbose_name='更新时间', auto_now=True) delete_time = models.DateTimeField(verbose_name='删除时间', null=True, blank=True) class Meta: abstract = True class CatsModel(SoftDeleteModel): name = models.CharField(max_length=25, verbose_name='名称') remark = models.CharField(max_length=200, verbose_name='备注', blank=True) def __str__(self): return self.name
|
如此,CatsModel
数据表中变自带了三个字段,其他模型同理。
Django
软删除
软删除也要用到字段复用,默认delete_time
为Null
,删除时该字段为当前删除时间,这样就形成了软删除。
网上有的说在模型里直接重写delete
方法,即可完成自定义软删除,我们来分析下我们的删除命令:
1
| TableModel.objects.filter(pk=2).delete()
|
可以看到是走了一个objects
的东西,如果你尝试过在模型类中重写delete
方法你会发现,这条命令根本不会走你自己的delete
方法。
objects是什么
默认情况下,Django
为每个Django
模型类添加一个模型管理类Manager
的对象为objects
。如果想要将这个对象修改为其他名称,那么可以用models.Manager()
来自定义创建对象
1 2 3 4 5 6 7 8 9 10
| class AREA(models.Model): .... area_obj = models.Manager()
class Meta: db_table = 'AREA'
AREA.area_obj.filter(pk=2).first() AREA.area_obj.filter(pk=2).delete()
|
软删除示例
创建自定义manager
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| from django.db import models from django.db.models.query import QuerySet from django.utils import timezone
class SoftDeleteQuerySet(QuerySet): def delete(self): self.update(delete_time=timezone.now())
class SoftDeleteManager(models.Manager): _queryset_class = SoftDeleteQuerySet
def get_queryset(self): kwargs = {'model':self.model, 'using':self._db} if hasattr(self, '_hints'): kwargs['hints'] = self._hints return self._queryset_class(**kwargs).filter(delete_time__isnull=True)
class SoftDeleteModel(models.Model): create_time = models.DateTimeField(verbose_name='添加时间', auto_now_add=True) update_time = models.DateTimeField(verbose_name='更新时间', auto_now=True) delete_time = models.DateTimeField(verbose_name='删除时间', null=True, blank=True) class Meta: abstract = True objects = SoftDeleteManager()
|
继承软删除模型
1 2 3 4 5
| class CatsModel(SoftDeleteModel): name = models.CharField(max_length=25, verbose_name='名称') remark = models.CharField(max_length=200, verbose_name='备注', blank=True) def __str__(self): return self.name
|
以上即完成了软删除的功能,迁移下数据库测试数据,看是否达到你想要的了!!!