軟刪除(Soft Delete)是一種數據刪除策略,它并不真正從數據庫中刪除記錄,而是通過標記(如 is_deleted 字段)來表示記錄已被刪除。
這樣做的好處是可以保留數據歷史,支持數據恢復和審計。
在 Django 里可以通過 自定義 Manager + 重寫 delete 方法 來實現。
1. 在模型里增加 is_delete
字段
from django.db import modelsclass BaseModel(models.Model):is_delete = models.BooleanField(default=False, verbose_name="是否刪除")class Meta:abstract = True # 抽象基類,不會建表
這樣所有繼承 BaseModel
的表都有 is_delete
字段。
2. 自定義 Manager(默認過濾掉刪除的記錄)
class ActiveManager(models.Manager):def get_queryset(self):# 默認只返回 is_delete=False 的數據return super().get_queryset().filter(is_delete=False)
3. 在模型里應用 Manager
class User(BaseModel):name = models.CharField(max_length=100)# managersobjects = ActiveManager() # 默認只取未刪除的all_objects = models.Manager() # 需要時可以取所有(包括已刪除的)
這樣:
User.objects.all() # 只會查 is_delete=False
User.all_objects.all() # 不加過濾,所有數據都能查
4. 重寫 delete()
方法(軟刪除)
class User(BaseModel):name = models.CharField(max_length=100)objects = ActiveManager()all_objects = models.Manager()def delete(self, using=None, keep_parents=False):self.is_delete = Trueself.save(update_fields=['is_delete']) # 只更新 is_delete 字段
這樣:
u = User.objects.get(id=1)
u.delete() # 不會真正刪除,只會把 is_delete 置為 True
5. 如果要做批量刪除
Django 的 QuerySet.delete()
默認會直接刪掉數據,所以我們也可以自定義一個 QuerySet
來支持批量軟刪除:
class SoftDeleteQuerySet(models.QuerySet):def delete(self):return super().update(is_delete=True)
結合 Manager 使用:
class ActiveManager(models.Manager):def get_queryset(self):return SoftDeleteQuerySet(self.model, using=self._db).filter(is_delete=False)
這樣就支持:
User.objects.filter(name="Tom").delete() # 也會變成軟刪除
? 總結:
is_delete
字段標記是否刪除。- 自定義 Manager 過濾掉已刪除的數據。
- 重寫
delete()
實現軟刪除邏輯。 - 如有需要,配合自定義
QuerySet
處理批量軟刪除。