2016-07-06 15 views
0

親モデルのフィールドの1つが変更されたときに、関連モデルの更新をトリガする最も適切な方法は何ですか?私はいくつかのインスタンスでActivityObject.is_deleted = Trueを設定した場合、私が望むすべてがあるモデルフィールドの変更に関する関連モデルの更新

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) 

その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() 

ただ、ここで推測するが、これの本当の目的はActivityObject sは削除され、関連するときActivityJob Sを削除する場合、その後、あなただけ先に行くと、削除することができますActivityObject。 Djangoのデフォルトの動作は、それに接続されているすべてのActivityJobを削除します。

削除時に他のアクションを実行する場合は、Djangoのpre_deleteまたはpost_deleteシグナルを使用します。指定したタイプのオブジェクトを削除する前後に定義する関数が呼び出されます。

EDIT:あなたはActivityObjectを扱うとis_deletedを変更するクエリセットにupdate()を使用している場合、あなたはActivityJobに対応するupdate()を実行することを確保するか、またはあなたはそれが自動的に実現するためにActivityObjectthisようqueryset機能を無効にすることができます。

+0

save()が呼び出されない場合はどうなりますか? – Brian

+0

@Brian 'ActivityObject'のデータベーステーブルが' save() 'を呼び出さずに変更された例を提供できますか? –

+0

@Yash Tewari私はこれが私の場合に最も適した解決策だと思う、thx – Compadre

0

Djangoシグナル 'pre_deleteまたはpost_deleteを使用できます。詳細と例は、Django Signals documentationにあります。

+0

そして、私は@ transaction.atomicデコレータによってシグナルキッチンですべてを包むことができますか?上の答えでは、 'save'メソッド全体をラップして、親オブジェクトが変更され、何らかの理由で関連オブジェクトが変更されないようにすることができます。 – Compadre

+0

これは役に立ちますか? http://django-atomic-signals.readthedocs.io/en/latest/ –

+0

この回答をお寄せいただきありがとうございます。私は、このソリューションは多くの点でより柔軟性があると理解していますが、外側の依存関係も含めてはるかに複雑です。このような柔軟性が必要な場合は、そのような問題を解決するあなたの方法を使用します。答えに時間を費やしてくれてありがとう:) – Compadre

関連する問題