私は次のモデルを持っています:
個人モデルには、質問との多対多(M2M)の関係があります。
class Person(models.Model):
name = models.CharField(max_length=100)
questions = models.ManyToManyField(Question, related_name='persons')
Djangoのデバッグツールバーから、次のように発行するとわかります。
persons = Person.objects.filter(name="Foo").prefetch_related("questions")
例外として、PersonテーブルとQuestionsテーブルの2つのクエリを実行します。
ただし、テンプレート内のリストをトラバースすると、Personの各行に対して追加のselectクエリが実行されます。
{% for person in persons %}
{{ person.name }}
{% for question in person.questions.all %}
{{ question.text }}
{% endfor %}
{% endfor %}
これは質問の2番目のSQLであるため、プリフェッチは確実に機能しますが、どういうわけか、各質問を表示するために追加のクエリが必要です。
SELECT ("myapp_person_questions"."person_id") AS "_prefetch_related_val",
"myapp_question"."id", "myapp_question"."asker_id",
"myapp_question"."question", "myapp_question"."timestamp"
INNER JOIN "myapp_person_questions" ON ("myapp_question"."id" =
"myapp_person_questions"."question_id") WHERE
"myapp_person_questions"."person_id" IN (1, 2, 3, 4) ORDER BY
"myapp_question"."timestamp" DESC
SELECT "myapp_question"."id", "myapp_question"."asker_id",
"myapp_question"."question", "myapp_question"."timestamp" FROM
"myapp_question" INNER JOIN "myapp_person_questions"
ON ("myapp_question"."id" = "myapp_person_questions"."question_id")
WHERE "myapp_person_questions"."person_id" = 1 ORDER BY "myapp_question"."timestamp" DESC
すべてのカスタムを無効にしManager
たので、で追加のフィルタリングが行われないことは間違いありませんQuerySet
。
注意すべき点の1つは、結合テーブルを自分で明示的に生成しないことです。これが問題になる可能性がありますか?(を使用してthrough
)