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

发布于 2024-12-07 14:15:32 字数 832 浏览 1 评论 0原文

在以下示例代码中:

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)

创建子级时 pre_save_parent 不会触发:

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

这是预期的行为吗?

In the following sample code:

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)

pre_save_parent doesn't fire when I a Child is created:

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

Is this expected behaviour?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

成熟稳重的好男人 2024-12-14 14:15:32

有一个关于此问题的开放票证,#9318

你的解决方法看起来不错。以下是 benbest86alexr 分别。

  1. 监听子类信号,并向那里发送父类信号。

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

    def pre_save_parent(发件人,**kwargs):
        如果不是 isinstance(实例,父级):
            返回
        #在这里做正常的信号处理
        打印“pre_save_parent”
    
    pre_save.connect(pre_save_parent)
    

There's an open ticket about this, #9318.

Your workaround looks fine. Here are two others suggested on the ticket by benbest86 and alexr respectively.

  1. Listen on the child class signal, and send the Parent signal there.

    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. Do not specify the sender when connecting the signal, then check for subclasses of parent.

    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)
    
痞味浪人 2024-12-14 14:15:32

我没有意识到 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 方法,并且它们反过来可以调用任何基类版本(如果存在)。

还有更好的解决方案吗?

I didn't realise sender was an optional parameter to connect. I can do the following:

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

This allows me to write per Model pre_save methods, and they in turn can call any base class versions (if they exists).

Any better solutions?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文