2017-03-22 13 views
2

refresh_from_dbを使用し、それをForeignKeyに自動的に伝播する方法はありますか?ForeignKeyのDjango refresh_from_db

model.py:

class TestItemModel(models.Model): 
    value = models.IntegerField(default=0) 
    relies_on_item = models.ForeignKey('self', on_delete=models.SET_NULL, blank=True, null=True) 

シェル:

>>> end_product = TestItemModel(value=1) 
>>> end_product.save() 
>>> container_product = TestItemModel(value=10,relies_on_item=end_product) 
>>> container_product.save() 
>>> end_product.pk 
12 
>>> end_product_for_update=TestItemModel.objects.get(pk=12) 
>>> end_product_for_update.value = 4 
>>> end_product_for_update.save() 
>>> container_product.relies_on_item.value 
1 
>>> container_product.refresh_from_db() 
>>> container_product.relies_on_item.value 
1 

この時点で返される値は、まだ初期のものです。 refresh_from_dbにForeignKeyによって参照される要素が自動的にカスケードされるようにするオプションはありますか?

下記の参照項目でrefresh_from_dbを明示的に使用することで可能です。しかし、私はcontainer_product自体にrefresh_from_dbを実行するだけでいいです。

シェル(続き):ジャンゴで

>>> container_product.relies_on_item.refresh_from_db() 
>>> container_product.relies_on_item.value 
4 
+0

自己参照モデルのカスケードをオーバーライドします。それは簡単に再帰ループにつながります。私はこれがカスケードとして実装されていない理由だと思います。必要な場合は、無限再帰の防止など、自分で追加する必要があります。 –

+0

どのバージョンのdjangoを使用していますか? – itzMEonTV

+0

@itzmeontv django 1.10.5。 –

答えて

1

私の知る限り、今refresh_from_dbのみ関係が除去されているか否かをチェックリレーショナルfields.Itのデータが更新されませんティル。しかし、あなたは(あなたがしたように)行うことができます。

for i in container_product._meta.concrete_fields: 
    if i.is_relation: 
     getattr(container_product, i.name).refresh_from_db() 

OR refresh_from_db

class Mymodel(models.Model): 
    def refresh_from_db(self, using=None, fields=None): 
     super(Mymodel, self).refresh_from_db(using=None, fields=None) 
     for i in self._meta.concrete_fields: 
      if i.is_relation and getattr(self, i.name): 
       getattr(self, i.name).refresh_from_db() 
+0

最後に仕事をしていただきありがとうございます。 getattrがNoneでないことを確認する必要がありました。それは無限再帰を防ぎませんが、それは私の特定のユースケースでは問題ではありません。 –

関連する問題