如何提高不存在-Django SoftDelete?

时间:2019-04-02 12:01:33

标签: django django-models django-queryset python-3.6 django-2.1

我有一个如下的抽象模型SoftDelete。

class SoftDeleteManager(models.Manager):

    def get_queryset(self):
        return super().get_queryset().filter(is_deleted=False)

class SoftDeleteModel(models.Model):
     is_deleted = models.BooleanField(default=0)
     deleted_at = models.DateTimeField(null=True)

     objects = SoftDeleteManager()

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

     class Meta:
        abstract = True

class Employee(SafeDeleteModel):
   pass

无论何时删除模型,我都会将is_deleted设置为True并更新时间戳记deleted_at,并创建自定义管理器来覆盖初始查询集,该查询集仅返回未删除的字段(is_deleted = False)

employee = Employee.objects.get(pk=1)
employee.delete()
employee.refresh_from_db() // not raising DoesNotExist

但是可以说我有一个Employee模型,该模型使用SafeDeleteModel进行软删除,当我调用Employee.objects.get(pk=1).delete()时删除了employee.refresh_from_db()这样的模型后,它不会引发{ {1}},但是按预期更新is_deleted,deleted_at的值,我在这里犯了什么错误,为什么它没有引发DoesNotExist

1 个答案:

答案 0 :(得分:0)

曾经有一个change in Django 2.1refresh_from_db()现在使用模型的_base_manager,而不是_default_manager,就像相关查询一样。这样可以确保即使默认管理器找不到对象也可以刷新对象。

因此,您应该使用SoftDeleteManagerbase_manager_name设置为基本管理员。但是请注意以下注释:

  

查询相关模型时不使用基本管理器。例如,如果本教程中的Question模型具有一个deleted字段和一个基本管理器,该基本管理器使用deleted=True过滤掉了实例,则类似Choice.objects.filter(question__name__startswith='What')的查询集将包含与删除的问题。

此外,我不知道在进行此更改后如何检索已删除的对象,除非您设置特殊管理器来过滤已删除的对象(例如{{1 }}。

请注意,我希望您在注释中引用的 safedelete 包也存在相同的问题,因为它也不会更改deleted_objects