Django:基本模型信号处理程序不会触发

时间:2011-10-03 21:14:50

标签: python django signals

在以下示例代码中:

from django.db import models
from django.db.models.signals import pre_save

# Create your models here.
class Parent(models.Model):
    name = models.CharField(max_length=64)

    def save(self, **kwargs):
        print "Parent save..."
        super(Parent, self).save(**kwargs)

def pre_save_parent(**kwargs):
    print "pre_save_parent"
pre_save.connect(pre_save_parent, Parent)

class Child(Parent):
    color = models.CharField(max_length=64)

    def save(self, **kwargs):
        print "Child save..."
        super(Child, self).save(**kwargs)

def pre_save_child(**kwargs):
    print "pre_save_child"
pre_save.connect(pre_save_child, Child)
当我创建一个Child时,

pre_save_parent不会触发:

child = models.Child.objects.create(color="red")

这是预期的行为吗?

2 个答案:

答案 0 :(得分:6)

有关于此的公开票,#9318

您的解决方法看起来很好。以下是benbest86alexr分别在故障单上建议的另外两个。

  1. 收听子类信号,并在那里发送父信号。

    def call_parent_pre_save(sender, instance, created, **kwargs):
        pre_save.send(sender=Parent, instance=Parent.objects.get(id=instance.id), created=created, **kwargs)
    pre_save.connect(call_parent_pre_save, sender=Child)
    
  2. 连接信号时不要指定发送方,然后检查父类的子类。

    def pre_save_parent(sender, **kwargs):
        if not isinstance(instance, Parent):
            return
        #do normal signal stuff here
        print "pre_save_parent"
    
    pre_save.connect(pre_save_parent)
    

答案 1 :(得分:2)

我没有意识到senderconnect的可选参数。我可以做到以下几点:

def pre_save_handler(**kwargs):
    instance = kwargs['instance']
    if hasattr(instance, 'pre_save'):
        instance.pre_save()
pre_save.connect(pre_save_handler)

这允许我按照模型pre_save方法编写,然后它们可以调用任何基类版本(如果它们存在)。

有更好的解决方案吗?