我有以下型號:Django prefetch_related造成M2M關係中的額外查詢
人員模型與問題具有多對多關係(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")
它2個查詢,一個Person表,爲例外另一個問題表。
但是,如果我遍歷模板中的列表,則會爲每行Person創建其他選擇查詢。
{% for person in persons %}
{{ person.name }}
{% for question in person.questions.all %}
{{ question.text }}
{% endfor %}
{% endfor %}
這是問題的第二個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
S,所以我敢肯定額外的濾波未在QuerySet
完成。
有一點要注意的是,我沒有明確地生成連接表我自己,這可能是問題嗎? (使用through
)
問題模型的外觀如何?它可能會以某種方式引用人員模型,使其再次查詢數據庫。 – Exelian 2012-08-17 10:22:40