2008-10-04 87 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