django 实现数据的逻辑删除

重写 queryset中的delete方法

from django.db.models.query import QuerySet


class LyQuerySet(QuerySet):
    def delete(self):
        """
        重写QuerySet的 delete方法实现数据的逻辑删除
        QuerySet 自带的delete方法会返回两个值 
            1.删除数据的条数
            2.{app.model:删除的条数} 
            例如: 3, {home.Banner:3} 表示删除了home app下面的Banner表中3条数据
        我们可以不返回不会报错,如果要返回也可以模仿一下
        :return:
        """
        del_query = self._chain()
        del_query.update(is_del=True)

自己实现Manager方法

# 使用我们自己的QuerySet来管理各种操作 BaseManager.from_queryset(LyQuerySet)
class LyManager(BaseManager.from_queryset(LyQuerySet)):
    def __init__(self, *args, **kwargs):
        self.__add_is_del_filter = True
        super(LyManager, self).__init__(*args, **kwargs)

    def get_queryset(self, *args, **kwargs):

        queryset = super(LyManager, self).get_queryset(*args, **kwargs)

        # 判断用户是否主动传入is_del的筛选条件,如果主动传入,就不做自动筛选操作
        if self.__add_is_del_filter:
            # 过滤掉已删除的记录
            queryset = queryset.filter(is_del=False)

        return queryset

    def filter(self, *args, **kwargs):

        # 判断用户是否主动传入is_del的筛选条件,如果主动传入,就不做自动筛选操作
        if not kwargs.get('is_del') is None:
            self.__add_is_del_filter = False
        f = super(LyManager, self).filter(*args, **kwargs)
        return f

使用自己的Manager对象来管理models

class LyModel(models.Model):
    """
    继承这个类的Model可以实现
    is_del为True的数据过滤 和 数据的逻辑删除
    """
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    is_del = models.BooleanField(verbose_name='是否删除', default=False)
    # 使用对象.delete()时也实现逻辑删除
    def delete(self, using=None, keep_parents=False):
        self.is_del = True
        self.save()

    # 使用自己的Manager对象来管理models
    objects = LyManager()

    class Meta:
        abstract = True

在编写model时继承自己的Model就可以实现,默认过滤is_del为True的数据和数据的逻辑删除

class Banner(LyModel):
    title = models.CharField(max_length=500, verbose_name="广告标题", null=True, blank=True)
    link = models.CharField(max_length=500, verbose_name="广告链接", null=True, blank=True)
    image_url = models.ImageField(verbose_name="广告图片", upload_to=upload_path_handler(), null=True, blank=True)
    remark = models.TextField(verbose_name="备注信息", null=True, blank=True)
    is_show = models.BooleanField(default=False, verbose_name="是否显示")
    orders = models.IntegerField(default=1, verbose_name="排序")

    class Meta:
        db_table = "ly_banner"
        verbose_name = "轮播广告"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.title
原文地址:https://www.cnblogs.com/wtil/p/14920816.html