2014-02-17 76 views
5

我使用pre_save和post_save信號將分析發送到Mixpanel。我寧願將這與模型的保存方法分開。Django:將變量從pre_save傳遞到post_save信號

當pre_save信號出現時,是否有辦法保存實例的舊值,然後在post_save上檢查它們的新值?

我的代碼如下所示:

@receiver(pre_save, sender=Activity) 
def send_user_profile_analytics(sender, **kwargs): 
    activity_completed_old_value = kwargs['instance'].is_completed 
    # store this value somewhere? 

@receiver(post_save, sender=Activity) 
def send_user_profile_analytics(sender, **kwargs): 
    if kwargs['instance'].is_completed != activity_completed_old_value: 
     # send analytics 

對於我來說,似乎更強大的使用post_save發送分析比pre_save,但在這一點上我看不出有什麼模型實例已更改。我想阻止在模型的保存函數中使用全局變量或實現某些內容。

回答

5

您可以將它們存儲爲實例屬性。

@receiver(pre_save, sender=Activity) 
def send_user_profile_analytics(sender, **kwargs): 
    instance = kwargs['instance'] 
    instance._activity_completed_old_value = instance.is_completed 

@receiver(post_save, sender=Activity) 
def send_user_profile_analytics(sender, **kwargs): 
    instance = kwargs['instance']  
    if instance.is_completed != instance._activity_completed_old_value: 
     # send analytics 

這樣您在save「送分析」,只在is_completed變化(這意味着save不只是存儲的價值,但提出了一些進一步的闡述)。

如果您想在實例生命週期(即從創建到創建時)更改字段時執行操作,則應在post_init(而不是pre_save)期間存儲初始值。

+0

我已經在想這個了,但是對於Django來說這是一個很好的做法嗎?爲什麼我會使它成爲受保護的屬性?感謝post_init提示,這確實更好。 – jvannistelrooy

+0

@jvannistelrooy:不需要受保護的屬性,但最好不要在這些函數之外使用這些附加屬性,因爲它們只是服務字段。我找到了這個解決方案...我會盡快發佈鏈接 – Don

+1

你能否請你解釋爲什麼'post_init'比'pre_save'好?即使實際上不需要這個值,它會不會添加額外的數據庫查詢? –