2016-04-24 19 views
3

Djangoデータモデルのクエリーセットの一括更新 - 多対多フィールドの更新方法を教えてください。Djangoクエリーセットの多対多フィールドを一括更新する方法

例えば、Photoというデータモデルと、PhotoStreamというデータモデルがあります。 Photoには、which_stream = models.ManyToManyField(PhotoStream)があります。

私はchildhood_photosと呼ばれるPhotosのクエリセットを抽出し、そして私は、このクエリセット内のすべてのオブジェクトの多対多のフィールドに新しいPhotoStreamオブジェクトを追加する必要があります。このPhotoStreamオブジェクトをfor_classmatesとしましょう。

私はchildhood_photos.update(which_stream.add(for_classmates))を試してみますが、それは私にエラーを与えます:グローバル名 'which_stream'は定義されていません

どうすればこの操作を行うことができますか?

答えて

3

m2n関係のスルーモデルは、フィールドの.through属性(documentationを参照)でアクセスできます。これにより、必要なモデルインスタンスを一括して作成することができます。

through_model = Photo.which_stream.through # gives you access to auto-created through model 
# print through_model 
# <class 'app_label.models.Photo_which_stream'> # or sth. similar 

through_model.objects.bulk_create([ 
    through_model(photo_id=pk, photostream_id=for_classmates.pk) 
     for pk in childhood_photos.values_list('pk', flat=True) 
]) 
+1

ありがとうございます。これを見れば、これは**新しいフィールドを作成することですが、 'through'テーブルだけにあります。私の心には、それは私が試していた**アップデート**の手順も同じです。したがって、それらは同等です。私はそれが私の頭の中で正しいことを確認したい、はい? –

+0

「スルーテーブル」だけではどういう意味ですか?スルーテーブルは 'ManyToManyField'のために本当に何かが起こる唯一の場所です!これは新しいフィールド(!?)を作成するのではなく、すべての目的の写真にfor_classmates'ストリームを追加します。 – schwobaseggl

+0

'update'操作を使うと、その特定のモデルにあるフィールドだけが更新されます。 M2Mフィールドについては、特定のテーブルでは実際には作成されませんが、1番目と2番目のテーブルに関連するデータベースには新しいスルーテーブルが作成されます。ストリームを更新するために 'Photo'モデルで' update'を実行することは、throughテーブルの行を作成することと同じではありません。 – AKS

関連する問題