71 lines
2.3 KiB
Python
71 lines
2.3 KiB
Python
from django.db import models
|
|
from django.utils import timezone
|
|
|
|
|
|
class BaseModel(models.Model):
|
|
"""基础模型,包含通用时间字段"""
|
|
created_at = models.DateTimeField('创建时间', auto_now_add=True)
|
|
updated_at = models.DateTimeField('更新时间', auto_now=True)
|
|
|
|
class Meta:
|
|
abstract = True
|
|
|
|
|
|
# ─── 软删除(停用 = 逻辑删除)────────────────────────────────────────────────────
|
|
|
|
class SoftDeleteQuerySet(models.QuerySet):
|
|
"""QuerySet.delete() 改为逻辑删除;hard_delete() 才物理删除。"""
|
|
|
|
def delete(self):
|
|
return self.update(is_deleted=True, deleted_at=timezone.now())
|
|
|
|
def hard_delete(self):
|
|
return super().delete()
|
|
|
|
def alive(self):
|
|
return self.filter(is_deleted=False)
|
|
|
|
|
|
class SoftDeleteManager(models.Manager):
|
|
"""默认只返回未删除的数据。"""
|
|
|
|
def get_queryset(self):
|
|
return SoftDeleteQuerySet(self.model, using=self._db).filter(is_deleted=False)
|
|
|
|
|
|
class AllObjectsManager(models.Manager):
|
|
"""包含已删除数据(管理/恢复用)。"""
|
|
|
|
def get_queryset(self):
|
|
return SoftDeleteQuerySet(self.model, using=self._db)
|
|
|
|
|
|
class SoftDeleteModel(BaseModel):
|
|
"""软删除基类:停用/下架一律逻辑删除,绝不物理删除。
|
|
|
|
- `objects`:默认管理器,只含未删除数据。
|
|
- `all_objects`:含已删除数据。
|
|
- 实例 `.delete()` → 逻辑删除;`.hard_delete()` → 物理删除。
|
|
"""
|
|
is_deleted = models.BooleanField('是否删除', default=False, db_index=True)
|
|
deleted_at = models.DateTimeField('删除时间', null=True, blank=True)
|
|
|
|
objects = SoftDeleteManager()
|
|
all_objects = AllObjectsManager()
|
|
|
|
class Meta:
|
|
abstract = True
|
|
|
|
def delete(self, using=None, keep_parents=False):
|
|
self.is_deleted = True
|
|
self.deleted_at = timezone.now()
|
|
self.save(using=using, update_fields=['is_deleted', 'deleted_at', 'updated_at'])
|
|
|
|
def hard_delete(self, using=None, keep_parents=False):
|
|
super().delete(using=using, keep_parents=keep_parents)
|
|
|
|
def restore(self, using=None):
|
|
self.is_deleted = False
|
|
self.deleted_at = None
|
|
self.save(using=using, update_fields=['is_deleted', 'deleted_at', 'updated_at'])
|