2013-07-15 45 views

回答

20

我將盡我所能,用一個例子來解釋一下:

pre_savepost_savesignals由模型發送。簡而言之,調用模型save之前或之後要執行的操作。

savetriggers the following steps

  • 發出預保存信號。
  • 預處理數據。
  • 大多數字段不做預處理 - 字段數據保持不變。
  • 準備數據庫的數據。
  • 將數據插入數據庫。
  • 發出保存後信號。

Django確實提供了一種覆蓋這些信號的方法。

現在,

pre_save信號可以覆蓋一些處理之前實際保存到數據庫中發生 - 例如:(我不知道在哪裏pre_save會在我的頭頂理想的一個很好的例子)

比方說你有一個ModelA,它存儲對ModelB所有對象的引用,它們有而不是被編輯。爲此,您可以註冊一個pre_save信號,在ModelBsave之前通知ModelA方法被調用(沒有什麼能阻止您在這裏註冊post_save信號)。現在

save方法(這是不是一個信號)的模型被稱爲 - 默認情況下,每種模式都有一個save方法,但是你可以重寫它:

class ModelB(models.Model): 
    def save(self): 
     #do some custom processing here: Example: convert Image resolution to a normalized value 
     super(ModelB, self).save() 

然後,您可以註冊post_save信號(這是更常用的是pre_save

一個常見的用例是UserProfile對象創建時在系統中創建對象User

您可以註冊一個post_save信號,該信號創建一個與系統中的每個User對應的對象UserProfile

信號是一種保持事物模塊化和明確的方法。 (明確地通知ModelA如果我save或改變東西在ModelB

我會想到更具體的現實世界的例子,試圖更好地回答這個問題。與此同時,我希望這可以幫助你

+0

感謝您的詳細解答。爲什麼'post_save'用於'UserProfile'創建的原因是因爲您可以在post_save中檢查實例是否被創建?(但不在pre_save中保存) – eugene

+0

您可能想要添加pre_save或post_save本身與交易無關。如果使用get_or_create或請求級事務,post_save將在事務內部發生,而不是在事務之後發生。根據數據庫的不同,您可以使用一些post_commit信號實現。 – ashwoods

3
pre_save 

在事務保存之前使用它。

post_save 

它在事務保存後使用。

可以使用pre_save例如,如果你有一個FileFieldImageField,看看fileimage確實存在。

如果您有UserProfile,並且您希望在創建新User時創建新的,則可以使用post_save

+0

您的'pre_save'示例中,您舉了一個例子來檢查文件是否存在,哪一個更適合使用信號或覆蓋save方法?因爲如果我在我的'pre_save'信號中添加驗證,我有問題會將錯誤提交給我的表單。 –

+0

@ Keda87如果你使用表單,我會去覆蓋表單的驗證功能。 –

+0

不! post_save通常在原子塊中調用。這意味着post_save在交易中發生。 – ashwoods

1

不要忘記遞歸風險。 如果使用instance.save()調用,而不是.update方法post_save方法,你應該斷開post_save信號:

Signal.disconnect(接收器=無,發件人=無, dispatch_uid = None)[source]要從信號中斷開接收器, 調用Signal.disconnect()。參數如 Signal.connect()中所述。如果接收器斷開連接,則返回True,否則返回False。

receiver參數指示註冊的接收器斷開連接。 如果使用dispatch_uid來標識接收者,它可能是None。

...然後再次連接。

更新()方法不發送pre_和post_信號,牢記它。

相關問題