Django中的软删除:get()。delete()v / s filter()。delete()

时间:2014-07-18 18:15:51

标签: django python-3.x django-models django-admin soft-delete

我最近通过覆盖django.db.models.query.QuerySetdjango.db.models.Manager在Django中实现了Soft Delete。

查询集:

class SoftDeleteQuerySet(QuerySet):
    def delete(self):
        super(SoftDeleteQuerySet, self).update(is_deleted=True, deleted=timezone.now())

    def delete_hard(self):
        super(SoftDeleteQuerySet, self).delete()

    def deleted(self):
        super(SoftDeleteQuerySet, self).filter(is_deleted=True)

管理器:

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

    def get_queryset(self):
        if self.show_deleted:
            return SoftDeleteQuerySet(self.model)
        return SoftDeleteQuerySet(self.model).filter(is_deleted=False)

    def delete_hard(self, instance):
        return self.get_queryset().delete_hard()

当我使用action删除change_list表单中的任何对象时,这非常正常。但是当我转到详细视图并尝试删除对象时,它已从数据库中完全删除

到目前为止,我已经发现问题是由 MyModel.objects.get(...)。delete()引起的。为了确保我没有走错方向,我在python shell中检查了它:

./ manage.py shell:

>> Status.objects.all().count()
2
>> Status.all_objects.all().count()
4

>> Status.objects.get(pk=4).delete()
>> Status.objects.all().count()
1
>> Status.all_objects.all().count()
3

>> Status.objects.filter(pk=9).delete()
>> Status.objects.all().count()
0
>> Status.all_objects.all().count()
3

如果有人可以解释我这种行为并建议我解决这个问题,那将会很棒。

Django 1.6.5

Python 3.4.0

提前致谢:)

1 个答案:

答案 0 :(得分:3)

Status.objects.get(pk=4).delete()

等同于此

obj = Status.objects.get(pk=4) # obj is now Status object
obj.delete()

因此,在这种情况下,不调用管理器方法。您可以直接在未被覆盖的对象上调用delete

然而

Status.objects.filter(pk=9).delete()

等于

qs = Status.objects.filter(pk=9) # qs is now SoftDeleteQuerySet object
qs.delete()

所以它会调用你的方法。