Django 中的软删除

SoftDelete in Django

问题陈述

我已经创建了一个基础模型:

class CreateUpdateDeleteModel(models.Model):
    from django.contrib.auth import get_user_model

    from django.utils.text import gettext_lazy as _

    from .managers import BakeryManager

    from drfaddons.datatypes import UnixTimestampField

    create_date = UnixTimestampField(_('Create Date'), auto_now_add=True)
    created_by = models.ForeignKey(get_user_model(), on_delete=models.PROTECT,
                                   related_name='%(app_label)s_%(class)s_creator')

    delete_date = models.DateTimeField(_('Delete Date'), null=True, blank=True)
    deleted_by = models.ForeignKey(get_user_model(), on_delete=models.PROTECT, null=True, blank=True,
                                   related_name='%(app_label)s_%(class)s_destroyer')

    update_date = models.DateTimeField(_('Date Modified'), auto_now=True)
    updated_by = models.ForeignKey(get_user_model(), on_delete=models.PROTECT, null=True, blank=True,
                                   related_name='%(app_label)s_%(class)s_editor')

    objects = BakeryManager()

    class Meta:
        abstract = True

我希望在我的系统中,所有元素都被软删除,即每当删除一个对象时,它应该表现如下:

  1. 表现得像正常的删除操作:如果 models.PROTECT 被设置为 on_delete 的值,则引发错误,如果它是 models.SET_NULL 则设置为空,依此类推。
  2. 设置delete_date
  3. 永远不要在任何查询中的任何地方(包括管理员)显示它。即使 model.objects.all() 也不应包含已删除的对象。

我该怎么做? 我正在考虑覆盖 get_queryset(),这可能会解决 problem 3。但是 1 & 2 呢?

很奇怪的要求。

第1点,不清楚。哪里显示错误?

第 2 点。删除是作为一种状态而不是数据的隐藏来管理的。我建议您添加一个状态字段并使用更改状态的特殊功能来管理删除。您可以覆盖 delete,但请注意,queryset 中的删除不会调用 Model.delete,而是直接调用 运行 SQL 代码。

说这是个坏主意。删除必须在那里,但只是没有使用。您可以轻松地从 Django 管理员中删除删除,开发人员没有理由删除代码,除非 he/she 不负责任地玩弄 Django shell。 (数据库备份?)

要点3.如果不想在admin中显示数据,只需覆盖Admin ModelForm,在对象的STATUS为DELETE时隐藏数据即可。操纵域以适应表示层是糟糕的设计。