2008-10-04 45 views
61

我在绕过这个时遇到了麻烦。现在我有一些模型,看起来有点像这样: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的信号分配器会有什么好处吗?

回答

67

保存/删除信号在情况普遍良好,你需要做哪些不是完全特定于问题的模型,也可以应用于具有一些共同点模型,或者可以跨越配置为使用变化楷模。在覆盖save方法

一个共同的任务是在模​​型自动生成蛞蝓的一些文本字段。这是一个例子,如果你需要实现它的一些模型,将受益于使用pre_save信号,其中信号处理程序可以采取slug字段的名称和字段的名称来生成slug 。一旦你有了这样的东西,你放置的任何增强功能也将适用于所有型号 - 例如查找您要添加的模型类型,以确保唯一性。

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

随着django-mptt,例如,我使用的pre_save信号来管理一组描述这样的将要被创建或更新模型的树形结构字段和所述pre_delete信号以去除树结构细节的对象是删除并删除其之前的所有对象的子树,并将其删除。由于使用的信号,用户不必添加或修改他们的模型savedelete的方法来对他们有这种管理做了,他们只需要让Django的MPTT知道他们想要它管理哪些车型。当你必须执行一些长期的过程,不希望阻止用户等待保存完成

3

如果你将使用信号你可以更新评价得分每次相关分数模型被保存。但是如果不需要这样的功能,我没有看到任何理由将其置于信号中,这与模型相关的东西很相似。

2

它是一种排序denormalisation的。看看这个pretty solution。就地组合字段定义。

-20

信号是有用的。

+8

没有,信号阻塞,除非你生成线程明确。 – muhuk 2011-07-10 04:58:49

+8

@ muhuk是对的,信号阻止你的过程。如果你想避免被阻塞的进程,可以使用gevent,celery或其他异步工具。 – pydanny 2011-12-13 21:27:29

11

你问:

会不会有使用Django的信号调度员什么好处?

我发现这个Django文档:

重写模型方法并不要求大容量操作

注意,对于一个对象的删除()方法不必称为 删除对象时批量使用QuerySet或作为级联删除的结果。为确保自定义的删除逻辑得到执行,您可以使用pre_delete和/或post_delete信号。

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

来源:Overriding predefined model methods