>我有一个抽象模型软删除,如下所示。
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
但是假设我有一个使用SafeDeleteModel
进行软删除的Employee
模型,当我调用employee.refresh_from_db()
时,它像Employee.objects.get(pk=1).delete()
一样删除模型后,它不会提高DoesNotExist
,而是更新is_deleted的值,deleted_at如预期的那样,我在这里犯了什么错误,为什么它没有提高DoesNotExist
?
Django 2.1 中有一个变化:refresh_from_db()
现在使用模型的_base_manager
,而不是像相关查询那样使用_default_manager
。这是为了确保即使默认管理器找不到对象,也可以刷新该对象。
因此,您应该使用base_manager_name
将SoftDeleteManager
设置为基本管理器。但请注意以下评论:
查询相关模型时不使用基本管理器。例如,如果本教程中的
Question
模型有一个deleted
字段和一个使用deleted=True
筛选出实例的基本管理器,则像Choice.objects.filter(question__name__startswith='What')
这样的查询集将包含与已删除问题相关的选项。
我也不知道在进行此更改后如何检索已删除的任何对象,除非您制作了一个特殊的管理器来不过滤已删除的对象(例如deleted_objects
)。
另请注意,我希望您在评论中提到的safedelete包有同样的问题,因为它也不会改变_base_manager
。