Django信号与重载保存方法

我有困难缠着这个。 现在我有一些看起来像这样的模型:

def Review(models.Model) ...fields... overall_score = models.FloatField(blank=True) def Score(models.Model) review = models.ForeignKey(Review) question = models.TextField() grade = models.IntegerField() 

评论有几个“分数”,overall_score是分数的平均值。 保存评论或评分时,我需要重新计算overall_score平均值。 现在我正在使用重写的保存方法。 使用Django的信号分配器会有什么好处吗?

保存/删除信号通常适用于需要进行更改的情况,这些更改不是完全特定于所讨论的模型,或者可以应用于具有某些共同点的模型,也可以configuration为跨模型使用。

重写的save方法中的一个常见任务是从模型中的某个文本字段自动生成slu </s>。 这是一个例子,如果你需要实现它的一些模型,将受益于使用pre_save信号,其中信号处理程序可以采取slug字段的名称和字段的名称,以产生slug 。 一旦你有了这样的东西,任何增强的function,你所采取的地方也将适用于所有模型 – 例如,查找你要添加的模型types的slu to,以确保唯一性。

可重复使用的应用程序通常受益于信号的使用 – 如果它们提供的function可以应用于任何模型,它们通常(除非不可避免)不希望用户必须直接修改模型才能从中受益。

例如,使用django-mptt ,我使用pre_save信号来pipe理一组描述即将创build或更新的模型的树结构的字段以及pre_delete信号,以删除被删除对象的树结构细节其之前的对象的整个子树被删除。 由于使用了信号,用户不需要在模型上添加或修改savedelete方法来完成这个pipe理,只需让django-mptt知道他们想要pipe理哪些模型。

你问:

使用Django的信号分配器会有什么好处吗?

我在django文档中发现了这个:

批量操作不会调用重写的模型方法

请注意,在使用QuerySet批量删除对象或级联删除的结果时,不一定会调用对象的delete()方法。 为了确保自定义的删除逻辑得到执行,可以使用pre_delete和/或post_delete信号。

不幸的是,在批量创build或更新对象时没有解决方法,因为没有调用save(),pre_save和post_save。

来自: 覆盖预定义的模型方法

如果您使用信号,则每次保存相关分数模型时,您都可以更新评分。 但是,如果不需要这样的function,我没有看到任何理由把这个信号,这是相当模型相关的东西。

这是一种非正规化。 看看这个漂亮的解决scheme 。 就地组合字段定义。

当您需要执行一些长期的过程并且不想阻止您的用户等待保存完成时,信号非常有用。