2016-07-06 52 views
0

當父模型的某個字段發生更改時,觸發相關模型更新的最合適方式是什麼?我有這樣的一組模型:相關型號模型現場更新更新

class ActivityObject(models.Model): 
    is_deleted = models.BooleanField(default=False) 

class ActivityJob(models.Model): 
    activity_object = models.ForeignKey(
     ActivityObject, 
     related_name='activity_jobs', 
    ) 
    is_deleted = models.BooleanField(default=False) 

,所以如果我在某些情況下設置ActivityObject.is_deleted = True所有我想要的是ActivityJob也發生了變化領域的is_deletedTrue所有相關實例。提前致謝。

回答

1

重寫保存()將工作:

class ActivityObject(models.Model): 
    is_deleted = models.BooleanField(default=False) 

    def save(self, *args, **kwargs): 
     super(ActivityObject, self).save(args, kwargs) 
     if self.is_deleted: 
      for job in self.activity_jobs: 
       job.is_deleted = True 
       job.save() 

只是猜測這裏,但如果這樣做的真正目的是爲了刪除ActivityJob■當相關ActivityObject s的刪除,那麼你可以繼續和刪除ActivityObject。 Django的默認行爲將刪除連接到它的所有ActivityJob

如果您想在刪除時執行一些其他操作,請使用Django的pre_deletepost_delete信號,它將調用您在刪除指定類型的對象之前/之後定義的函數。

編輯:如果你曾經使用update()關於處理ActivityObject和改變is_deleted查詢集,你可以保證你在ActivityJob進行相應update(),或者你可以重寫ActivityObjectqueryset功能,例如this使其自動發生。

+0

如果save()永遠不會被調用? – Brian

+0

@Brian你可以提供一個例子,其中「ActivityObject」的數據庫表在沒有調用save()的情況下被更改嗎? –

+0

@Yash Tewari我認爲這是對我來說最合適的解決方案,thx – Compadre

0

您可以使用Django信號'pre_deletepost_delete。更多的細節和例子可以在Django Signals documentation中找到。

+0

我可以通過@ transaction.atomic裝飾器將信號廚房的整個東西包裹起來嗎?因爲在上面的答案中,我可以包裝整個'save'方法,並且感覺保存是否會更改父對象,並且由於某些原因相關對象不會被更改。 – Compadre

+0

這會有幫助嗎? http://django-atomic-signals.readthedocs.io/en/latest/ –

+0

感謝這個答案,我明白這個解決方案在許多方面更加靈活,但它也複雜得多,包括外部依賴。如果我需要這種靈活性,我會用你的方式來解決這類問題。感謝花時間回答:) – Compadre