忽略 django 的 post_save 信号中对 m2m 关系的更改

Posted

技术标签:

【中文标题】忽略 django 的 post_save 信号中对 m2m 关系的更改【英文标题】:Ignore changes to m2m relationship in post_save signal of django 【发布时间】:2021-10-26 04:52:27 【问题描述】:

我有一个关于 django 信号的问题。

假设我有这些模型:

class Parent(models.Model):
    parent_name = (...)

class Children(models.Model):
    child_name  = (...)
    parent      = models.ForeignKey(Parent, on_delete=models.CASCADE, related_name='children')

假设我将此信号连接到Parent 类的post_save 信号:

def handle(*args, **kwargs):
   (...)

post_save.connect(handle, sender=Parent)

现在,如果我创建一个新孩子:

some_parent = Parent.objects.get(...)
new_child = Child.objects.create(
    ...,
    parent = some_parent
)

即使我只是创建一个新的Child,Django 也会从some_parent 发送一个post_save 信号,因此handle 将被调用。有没有办法忽略这个信号?类似的东西:

def handle(*args, **kwargs):
    if <some_condition>: # check if the signal is sent just because a new child is created
        # Ignore the signal
        return
    # Do everything as usual
    ...

【问题讨论】:

我试过了,创建孩子的时候一直没有收到信号。仅当显式调用父级上的save 时。您确定没有其他方法在父级上调用 save 吗? 代码库很大。我不知道。我会检查一下。感谢您指出这个提示。 【参考方案1】:

当然,post_save 处理程序的第一个参数是 instancecreated

@receiver(models.signals.post_save, sender=Parent)
def handle(instance, created, **kwargs):
    if created:
        return
    do_thingamy()

【讨论】:

以上是关于忽略 django 的 post_save 信号中对 m2m 关系的更改的主要内容,如果未能解决你的问题,请参考以下文章

Django:如何在 post_save 信号中访问原始(未修改)实例

Django 从 post_save 信号访问 ManyToMany 字段

如何防止灯具与 django post_save 信号代码冲突?

Django post_save() 信号实现

Django post_save 信号和 celery 任务之间可能的竞争条件

如何使用 Django 信号(Pre_save,Post_save)从“B”模型的 ImageField 设置“A”模型的 ImageField