如何引发 DoesNotExist - Django SoftDelete?

How to Raise DoesNotExist - Django SoftDelete?

我有一个抽象模型 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,并创建自定义管理器来覆盖 return 仅未删除的初始查询集字段(is_deleted=假)。

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

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

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

因此您应该使用 base_manager_name 将您的 SoftDeleteManager 设置为基本管理员。但请注意这条评论:

Base managers aren’t used when querying on related models. For example, if the Question model from the tutorial had a deleted field and a base manager that filters out instances with deleted=True, a queryset like Choice.objects.filter(question__name__startswith='What') would include choices related to deleted questions.

此外,我不知道您如何在进行此更改后检索已删除的任何对象,除非您让一个特殊的管理器过滤已删除的对象(例如 deleted_objects)。

另请注意,我希望您在评论中提到的 safedelete 包有同样的问题,因为它也没有改变 _base_manager