重写 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