【问题标题】:Soft Deletion in Django: get().delete() v/s filter().delete()Django 中的软删除:get().delete() v/s filter().delete()
【发布时间】:2014-09-09 23:13:10
【问题描述】:

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

查询集:

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()

当我使用操作从 change_list 表单中删除任何对象时,这绝对可以正常工作。但是当我转到详细视图并尝试删除该对象时,它已完全从数据库中删除

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

./manage.py 外壳:

>> 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

在此先感谢 :)

【问题讨论】:

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


    【解决方案1】:

    这个

    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()
    

    所以它确实调用了你的方法。

    【讨论】:

    • 这个obj.delete() 方法在哪里定义呢?它住在哪里?为什么要单独定义?最后的解决方案? :) 谢谢
    • 它应该在您的情况下在Status 模型中定义。也可以在那里覆盖它。
    • 哦,我明白了,完全错过了。谢谢,试试看。
    猜你喜欢
    • 2020-10-26
    • 1970-01-01
    • 2020-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-05
    • 2011-10-20
    • 2021-03-13
    相关资源
    最近更新 更多