编辑 many_to_many 字段时避免 Django 中的重复信号
Avoiding duplicate signals in Django when editing many_to_many fields
我想自动更新有关模型更改的外部应用程序。问题是数据在事件 <-> 用户之间处于多对多关系。我尝试使用"m2m_changed" signal。
@receiver(m2m_changed, sender=models.Event.organisers.through)
def event_changed(sender, instance, action, *args, **kwargs):
if "post" in action:
# hey api here is the new list of organisers of this
这个问题是,如果我在删除一个用户并添加另一个用户的地方进行一次更改,那么这段代码将被调用两次!那不好,我不能如果仅调用该操作,则忽略一种类型的操作。我曾想过将实例推入堆栈并忽略重复项,但这看起来很乱。有没有办法让我自己的信号只触发一次?
中继似乎无法很好地回答这个问题,所以这里有一些有用的解决方法,比我最初想象的要好。
解决方案 1:
不是组合信号,而是将实例的主键添加到集合中以忽略重复信号:
updated = set()
@receiver(m2m_changed, sender=models.Event.organisers.through)
def event_changed(sender, instance, action, *args, **kwargs):
if "post" in action:
updated.add(instance.pk)
def send_updates():
for Event in updated: # Iteration AKA for each element
#update code here
虽然这需要对 运行 send_updates() 进行某种计划任务,但如果事件有许多连续更改,它可以避免发送垃圾邮件的机会。
解决方案 2
完全忽略信号将上次修改添加到模型中。然后 运行 查询以获取从现在到上次调用 send_updates() 之间的所有事件。将最后一次调用存储到 disk/database 以避免在重新启动时重新发送所有内容。
Django m2m_changed
表示对 ManyToMany 模型的更改。如果有 4 个动作
- pre_add
- post_add
- pre_remove
- post_remove
因此,如果您只是添加用户,此 m2m_changed 方法将被触发 2 次,分别为 pre_add
和 post_add
。
您可以指定要调用的操作 API。可以这样做:
@receiver(m2m_changed, sender=models.Event.organisers.through)
def event_changed(sender, instance, action, *args, **kwargs):
if kwargs.get('action') == 'pre_add': # Or whatever action you want
# Call your API here
参考 Django 文档:https://docs.djangoproject.com/en/2.2/ref/signals/#m2m-changed
我想自动更新有关模型更改的外部应用程序。问题是数据在事件 <-> 用户之间处于多对多关系。我尝试使用"m2m_changed" signal。
@receiver(m2m_changed, sender=models.Event.organisers.through)
def event_changed(sender, instance, action, *args, **kwargs):
if "post" in action:
# hey api here is the new list of organisers of this
这个问题是,如果我在删除一个用户并添加另一个用户的地方进行一次更改,那么这段代码将被调用两次!那不好,我不能如果仅调用该操作,则忽略一种类型的操作。我曾想过将实例推入堆栈并忽略重复项,但这看起来很乱。有没有办法让我自己的信号只触发一次?
中继似乎无法很好地回答这个问题,所以这里有一些有用的解决方法,比我最初想象的要好。
解决方案 1:
不是组合信号,而是将实例的主键添加到集合中以忽略重复信号:
updated = set()
@receiver(m2m_changed, sender=models.Event.organisers.through)
def event_changed(sender, instance, action, *args, **kwargs):
if "post" in action:
updated.add(instance.pk)
def send_updates():
for Event in updated: # Iteration AKA for each element
#update code here
虽然这需要对 运行 send_updates() 进行某种计划任务,但如果事件有许多连续更改,它可以避免发送垃圾邮件的机会。
解决方案 2
完全忽略信号将上次修改添加到模型中。然后 运行 查询以获取从现在到上次调用 send_updates() 之间的所有事件。将最后一次调用存储到 disk/database 以避免在重新启动时重新发送所有内容。
Django m2m_changed
表示对 ManyToMany 模型的更改。如果有 4 个动作
- pre_add
- post_add
- pre_remove
- post_remove
因此,如果您只是添加用户,此 m2m_changed 方法将被触发 2 次,分别为 pre_add
和 post_add
。
您可以指定要调用的操作 API。可以这样做:
@receiver(m2m_changed, sender=models.Event.organisers.through)
def event_changed(sender, instance, action, *args, **kwargs):
if kwargs.get('action') == 'pre_add': # Or whatever action you want
# Call your API here
参考 Django 文档:https://docs.djangoproject.com/en/2.2/ref/signals/#m2m-changed