6

我在我的 django 管理员中使用软删除,就像这样。问题是当我删除一个外键项目时,它似乎并没有触发它链接到的所有项目的删除。或者它可能会,但它没有运行我在我的模型上拥有的自定义def delete 。

- 如果我删除一个人,那么他们将被软删除,但相关帐户保持不变。

- 如果我删除软删除,那么当我删除一个人时,帐户也会被删除,这是正确的。

因此,理想情况下,当我删除一个人时,我希望它软删除该人,并且引用该人的帐户也被软删除(将它们标记为非活动)。

class Person(models.Model):
    description = models.CharField(max_length=100)

    def delete(self, *args, **kwargs):
        self.active = False
        self.deleted_date = datetime.now()
        self.save()

class Account(models.Model):
    name = models.CharField(max_length=50)
    person = models.ForeignKey(Person, null=True, blank=True)
    active = models.BooleanField(default=True, editable=False)

    objects = SoftDeleteManager()

    def delete(self, *args, **kwargs):
        self.active = False
        self.deleted_date = datetime.now()
        self.save()

    def __unicode__(self):
        return "%s: %s" % (self.type,self.name)

更新:我已经更新了这个问题。我没有说我在 Person 模型上运行软删除。还补充说,当 def 删除未被覆盖时,级联删除工作,但是当我覆盖删除时,级联不会触发。

4

2 回答 2

4

您的Person模型目前不是为“软”删除而设计的。当你删除一个Person对象时,Django 会删除所有相关的Account对象。如果要软删除Person对象,请在Person模型中为其添加一个标志。然后,您需要确保您的默认Account管理器排除与软删除的 Person 对象相关的那些帐户。

编辑:

  1. 一种方法是让默认管理器排除与非活动 Person 对象相关的对象,而不是将它们设置为“已删除”:

      class AccountManager(models.Manager): 
          def get_query_set(self):
              return self.filter(person__active=True).filter(active=True)
    
  2. 另一种方法是在软删除 Person 对象时将相关的 Account 对象设置为“已删除”。为此,您可以使用信号。我认为 Person 对象上的保存后信号是合适的

于 2011-07-04T09:05:00.663 回答
0

另一种解决方案是使用 django-softdelete,这是一个最近出现在 github 上的 Django 包:https ://github.com/scoursen/django-softdelete

如果您为模型使用提供的 SoftDeleteObject mixin,删除它们将自动导致所有相关模型的软删除。更好的是它存储了软删除中相关的所有模型,因此您也可以通过一次取消删除调用来取消删除所有模型。

于 2011-08-12T20:31:47.973 回答