すでに投稿された回答を確認します。実際の例で答えを追加した方がいいと思いました。
関連する3つのDjangoモデルがあるとします。
class M1(models.Model):
name = models.CharField(max_length=10)
class M2(models.Model):
name = models.CharField(max_length=10)
select_relation = models.ForeignKey(M1, on_delete=models.CASCADE)
prefetch_relation = models.ManyToManyField(to='M3')
class M3(models.Model):
name = models.CharField(max_length=10)
ここでは、問い合わせることができM2
モデルとその相対的なM1
使用してオブジェクトをselect_relation
フィールドとM3
使用してオブジェクトをprefetch_relation
フィールド。
ただし、M1
のリレーションはM2
isであるForeignKey
ことを説明したように、オブジェクトのレコードは1つだけ返されM2
ます。同じことが当てはまりOneToOneField
ます。
しかし、M3
の関係はでM2
あり、ManyToManyField
任意の数のM1
オブジェクトを返す可能性があります。
2つのM2
オブジェクトがありm21
、ID m22
が同じ5つのM3
オブジェクトが関連付けられている場合を考えます1,2,3,4,5
。M3
これらの各オブジェクトに関連付けられたオブジェクトをフェッチするときにM2
、select relatedを使用すると、これが動作します。
手順:
m21
オブジェクトを検索します。
- IDがである
M3
オブジェクトに関連するすべてのオブジェクトを照会しm21
ます1,2,3,4,5
。
m22
オブジェクトと他のすべてのM2
オブジェクトについて同じことを繰り返します。
私たちは同じ持っているように1,2,3,4,5
、両方のIDをm21
、m22
私たちはselect_relatedオプションを使用する場合は、オブジェクトは、すでにフェッチされた同じIDの二回DBを照会するために起こっています。
代わりに、prefetch_relatedを使用する場合、M2
オブジェクトを取得しようとすると、M2
テーブルのクエリ中にオブジェクトが返したすべてのID(注:IDのみ)が記録され、最後のステップとして、DjangoがM3
テーブルにクエリを実行しますM2
オブジェクトが返したすべてのIDのセット。M2
データベースの代わりにPythonを使用してオブジェクトに結合します。
この方法では、すべてのM3
オブジェクトを1回だけクエリするので、パフォーマンスが向上します。