Python Django检测许多领域的变化

Python Django检测许多领域的变化,python,django,Python,Django,我有一个与用户模型有很多关系的模型: class ExtraModel(models.Model): ... extra_relation = models.ManyToManyField(User, blank=True, related_name='extra_relation') 当用户被添加到这个多人字段时,我想向他们发送一封电子邮件。我们可以在任何时候添加它们,这种情况经常会发生多次(即一次添加几个用户) 我一直在研究实现这一点的最佳方法,我认为应该使用m2m\u c

我有一个与用户模型有很多关系的模型:

class ExtraModel(models.Model):
    ...
    extra_relation = models.ManyToManyField(User, blank=True, related_name='extra_relation')
当用户被添加到这个多人字段时,我想向他们发送一封电子邮件。我们可以在任何时候添加它们,这种情况经常会发生多次(即一次添加几个用户)

我一直在研究实现这一点的最佳方法,我认为应该使用
m2m\u changed
信号。似乎Django(或者至少通过管理面板)首先清除所有关系,然后再次将它们插入。看看发射的信号,我看到了“pre_clear”、“post_clear”、“pre_add”和“post_add”

问题是'pre_add'和'post_add'中的'pk_set'是相同的,并且'pre_clear'和'post_clear'没有任何'pk_set'属性。因此,即使我能够在“pre_clear”(我不太知道如何收集)阶段确定如何收集PK,我也必须保存它们,以便在“post_save”阶段进行比较(确定添加了哪些用户)


有没有一种好的方法可以做到这一点?使用信号或其他方式。

您使用m2m\U更改的信号是正确的

您只需等待添加每个m2m,并作为发送方通过表传递:

m2m_changed.connect(method, sender=ExtraModel.extra_relation.through)
然后在您的方法中:

method(sender, instance, **kwargs):
    extra_relations = instance.extra_relations.all()
    ...


关于,

谢谢,这有助于缩小范围。问题是,当Django管理面板“添加”一个新关系时,它实际上会在添加所有键(加上新键)之前删除所有键。因此,如果我调用
instance.extra_relations.all()
,它向我展示了所有的关系,而不仅仅是新的关系。如果我查看“动作”触发信号,我可能会查看“清除前”和“添加后”中的键之间的差异,即在添加新键之前和之后。但是如何将键从“清除前”保存到“添加后”上的访问信号?哦,那我真的不明白你的问题是什么,对不起。但我不明白为什么post和pre add pk_集是相同的是一个问题?在这两种情况下,它应该只包含添加的m2m对象的pk…你是说它也包含以前的,已经保存的对象吗?是的。因为管理模块似乎通过remov来清理条目对所有保存的对象进行初始化,然后重新添加所有对象,
pk\u集
是所有对象,包括以前存在的对象。