我看到我可以覆蓋或定義pre_save, save, post_save
做模型實例保存時我想要的。何時使用pre_save,保存在django中的post_save?
哪一個在哪種情況下更好?爲什麼?
我看到我可以覆蓋或定義pre_save, save, post_save
做模型實例保存時我想要的。何時使用pre_save,保存在django中的post_save?
哪一個在哪種情況下更好?爲什麼?
我將盡我所能,用一個例子來解釋一下:
pre_save
和post_save
是signals由模型發送。簡而言之,調用模型save
之前或之後要執行的操作。
甲save
triggers the following steps
Django確實提供了一種覆蓋這些信號的方法。
現在,
pre_save
信號可以覆蓋一些處理之前實際保存到數據庫中發生 - 例如:(我不知道在哪裏pre_save
會在我的頭頂理想的一個很好的例子)
比方說你有一個ModelA
,它存儲對ModelB
所有對象的引用,它們有而不是被編輯。爲此,您可以註冊一個pre_save
信號,在ModelB
的save
之前通知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
)
我會想到更具體的現實世界的例子,試圖更好地回答這個問題。與此同時,我希望這可以幫助你
pre_save
在事務保存之前使用它。
post_save
它在事務保存後使用。
可以使用pre_save
例如,如果你有一個FileField
或ImageField
,看看file
或image
確實存在。
如果您有UserProfile
,並且您希望在創建新User
時創建新的,則可以使用post_save
。
您的'pre_save'示例中,您舉了一個例子來檢查文件是否存在,哪一個更適合使用信號或覆蓋save方法?因爲如果我在我的'pre_save'信號中添加驗證,我有問題會將錯誤提交給我的表單。 –
@ Keda87如果你使用表單,我會去覆蓋表單的驗證功能。 –
不! post_save通常在原子塊中調用。這意味着post_save在交易中發生。 – ashwoods
不要忘記遞歸風險。 如果使用與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_信號,牢記它。
感謝您的詳細解答。爲什麼'post_save'用於'UserProfile'創建的原因是因爲您可以在post_save中檢查實例是否被創建?(但不在pre_save中保存) – eugene
您可能想要添加pre_save或post_save本身與交易無關。如果使用get_or_create或請求級事務,post_save將在事務內部發生,而不是在事務之後發生。根據數據庫的不同,您可以使用一些post_commit信號實現。 – ashwoods