2012-02-19 23 views

答えて

2

中間テーブル(throughを使用)を指定せずにManyToManyFieldを作成すると、Djangoがテーブルを生成します。この表は両方のモデルのpksだけを必要とするため、新しいリレーションシップを保存するために他のオブジェクトから何かを選択する必要はありません。

複数の挿入を使用する可能性がありますが、必ずしも多くのデータベース呼び出しを必要とすることはありません(複数の挿入コマンドを含む単一のSQLクエリが可能です)。それらの作成に必要なすべての情報(オブジェクトのpk)はすぐに利用できるので、必要以上のデータベースヒットは必要ありません。

更新:私は間違っていたようです。ソース(ジャンゴ/ DB /モデル/フィールド/ related.py)を見ると、私はそれがオブジェクトごとに独立した作成を実行することを見た:PKSのいずれかが提供されている場合その前に

for obj_id in new_ids: 
    self.through._default_manager.using(db).create(**{ 
     '%s_id' % source_field_name: self._pk_val, 
     '%s_id' % target_field_name: obj_id, 
    }) 

を、それもチェック

vals = self.through._default_manager.using(db).values_list(target_field_name, flat=True) 
vals = vals.filter(**{ 
    source_field_name: self._pk_val, 
    '%s__in' % target_field_name: new_ids, 
}) 
new_ids = new_ids - set(vals) 

このチェックは、単一のクエリを使用して行われているものの...

0

は、あなたが自分で使用していることを確認しようとしたしました:すでに(重複したエントリ/一意性制約違反を避けるために)データベースに存在していましたQuerySet.query属性?

+3

'add'と' remove'にはチェックするクエリ属性がありませんが、同様のアプローチがあります。 'django.db import connection'を実行してから、多くの関係を追加または削除する前後に' connection.queries'を表示します。 – Alasdair

+0

ありがとう、それについて知らなかった。 – side2k

関連する問題