Да дело-то не в том, что значения по ForeignKey тащатся отдельными запросами. Данный код должен вытыщить несколько строк таблицы. Дело в том, что код получается работает в два этапа:
1) Составляется довольно-таки грамотный запрос, учитывающий связи, и все, что нужно. Этот запрос возвращает итерабильный QuerySet.
2) При запросе во время очередной итерации следующего элемента, QuerySet генерирует ОДИН SQL запрос и тащит ОДНУ строку из таблицы, по ‘id’. И так каждый раз.
В случае, когда для формирования вебстраницы нужно из одной таблицы вытащить штук 50 строк, это все может быть затратным.
Если посмотреть в потроха, выглядит все это примерно так:
Первый запрос, возвращающий QuerySet
SELECT "multilang_msgtext"."id", "multilang_msgtext"."lang_id", "multilang_msgtext"."msg_id", "multilang_msgtext"."text" FROM "multilang_msgtext" INNER JOIN "multilang_lang"
ON ("multilang_msgtext"."lang_id" = "multilang_lang"."id") INNER JOIN "multilang_msg" ON ("multilang_msgtext"."msg_id" = "multilang_msg"."id")
INNER JOIN "multilang_page" ON ("multilang_msg"."page_id" = "multilang_page"."id")
WHERE ("multilang_lang"."name" = E'Russian' AND "multilang_page"."name" = E'site_header_1' )
Последующие запросы:
.....
SELECT "multilang_msg"."id", "multilang_msg"."page_id", "multilang_msg"."msgnum", "multilang_msg"."name", "multilang_msg"."comment"
FROM "multilang_msg" WHERE "multilang_msg"."id" = 20
.....
Я вижу смысл в определенных случаях (нужно много записей из одной таблицы), получить все записи одним запросом, используя самописный SQL. Это здорово экономит ресурсы, а код почти не усложняет.