django - 如何在更改指定字段时自定义模型保存方法

时间:2016-10-14 04:08:11

标签: python django save

我有一个模型,让我们保存A,定义如下:

class A(models.Model):
   name = models.CharField('name', max_length=10)
   enabled = models.BooleanField('enabled', default=False)
   field1 = models.CharField('field1', max_length=10)
   field2 = models.CharField('field2', max_length=10)
   field3 = models.CharField('field3', max_length=10)
   parent = models.ForeignKey('self', null=True, blank=True) # hierarchy

和该模型的一些对象实例,a,b,c,d。层次结构由父字段表示。

a 
|-- b
    |-- c
    |-- d

所以,我需要做的是,当b.enabledFalse更改为True时,反之亦然,我需要更新c.enabled和{{1} }值:d.enabled

也就是说,当父级的b.enabled字段发生更改时,我需要将更改广播到子实例。

出于性能考虑,我只需要在enabled字段真正更改时广播更改。并且不希望在父节点保存时始终更新子实例,例如只更新field1或field2。

那么,有谁知道,实现这种逻辑的最佳方法是什么?提前谢谢。

2 个答案:

答案 0 :(得分:1)

总之 - 没有。但你可以手动重载保存方法。

class B(models.Model):

    ...

    def save(self, *args, **kwargs):
        if self.pk is not None:
            original = B.objects.get(pk=self.pk)
            if original.enabled != self.enabled:
                C.enabled = self.enabled
                C.save()
                D.enabled = self.enabled
                D.save()
        super(B, self).save(*args, **kw)

答案 1 :(得分:1)

执行此操作的最佳方法是使用django信号https://docs.djangoproject.com/es/1.10/ref/signals/

当模型调用方法save()

时,您将调用方法change_status
from django.db.models.signals import pre_save

def change_status(sender, instance, **kwargs):
    # instance object is the model that you have called the method save
    a = A.objects.get(id=instance.id) # or B or C model
    if instance.enable:
        a.enable = False
        # my code.....

pre_save.connect(change_status, sender=A) 
# sender is the model that will be called every time you call the method save

那就是它 请记住,在更改之前,对象实例是您的模型,因此 如果您有a.enable=True并在change_status信号中调用方法save(),则无需更改a.enable=True即可进行查询 intance.enable >> Truea.enable >> False因为a尚未保存。