DeleteView标记为无效,而不是删除?

时间:2018-10-11 19:56:44

标签: python django

使用Django的DeleteView是否有一些优雅的解决方案,但实际上是删除对象,将它们标记为不活动?我喜欢DeleteView的简单性,但希望将数据保留在后端,而不是删除它。

3 个答案:

答案 0 :(得分:2)

优雅的解决方案将覆盖ModelManager以更新delete上的字段。这是作为抽象模型的实现,因此可以被任何其他模型扩展。如果模型中已经有删除字段,则可以根据需要进行修改。

软删除抽象模型

class SoftDeletionModel(models.Model):
    deleted_at = models.DateTimeField(blank=True, null=True)

    objects = SoftDeletionManager()
    all_objects = SoftDeletionManager(alive_only=False)

    class Meta:
        abstract = True

    def delete(self):
        self.deleted_at = timezone.now()
        self.save()

    def hard_delete(self):
        super(SoftDeletionModel, self).delete()

对象管理器

class SoftDeletionManager(models.Manager):
    def __init__(self, *args, **kwargs):
        self.alive_only = kwargs.pop('alive_only', True)
        super(SoftDeletionManager, self).__init__(*args, **kwargs)

    def get_queryset(self):
        if self.alive_only:
            return SoftDeletionQuerySet(self.model).filter(deleted_at=None)
        return SoftDeletionQuerySet(self.model)

    def hard_delete(self):
        return self.get_queryset().hard_delete()

QuerySet

class SoftDeletionQuerySet(QuerySet):
    def delete(self):
        return super(SoftDeletionQuerySet, self).update(deleted_at=timezone.now())

    def hard_delete(self):
        return super(SoftDeletionQuerySet, self).delete()

    def alive(self):
        return self.filter(deleted_at=None)

    def dead(self):
        return self.exclude(deleted_at=None)

有关说明,请参见Soft Deletion in Django

答案 1 :(得分:1)

DeleteView继承了DeletionMixin,因此您可以预定义delete方法。 DeletionMixin

答案 2 :(得分:1)

按如下方法在DeleteView中覆盖删除方法

class Example(DeleteView):
    def delete(self, request, *args, **kwargs):  
    """
    Calls the delete() method on the fetched object and then
    redirects to the success URL.
    """
            self.object = self.get_object()
            self.object.is_deleted = True # Declare a boolean field is_deleted in your model. Default value is Flase.
            return HttpResponseRedirect(self.get_success_url())