Рассмотрим select_related () .
От 3 запросов до 2 запросов только с select_related (), до 1 запроса с select_related () с лучшими аргументами.
In [17]: [q.user.userdata.access_token for q in Question.objects.all()]
DEBUG (0.000) SELECT "testapp_question"."id", "testapp_question"."description", "testapp_question"."pub_date", "testapp_question"."image_url", "testapp_question"."user_id" FROM "testapp_question"; args=()
DEBUG (0.000) SELECT "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."id" = 1 ; args=(1,)
DEBUG (0.000) SELECT "testapp_userdata"."id", "testapp_userdata"."user_id", "testapp_userdata"."access_token", "testapp_userdata"."profile_image_url" FROM "testapp_userdata" WHERE "testapp_userdata"."user_id" = 1 ; args=(1,)
Out[17]: [u'1']
In [18]: [q.user.userdata.access_token for q in Question.objects.all().select_related()]
DEBUG (0.000) SELECT "testapp_question"."id", "testapp_question"."description", "testapp_question"."pub_date", "testapp_question"."image_url", "testapp_question"."user_id", "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "testapp_question" INNER JOIN "auth_user" ON ("testapp_question"."user_id" = "auth_user"."id"); args=()
DEBUG (0.000) SELECT "testapp_userdata"."id", "testapp_userdata"."user_id", "testapp_userdata"."access_token", "testapp_userdata"."profile_image_url" FROM "testapp_userdata" WHERE "testapp_userdata"."user_id" = 1 ; args=(1,)
Out[18]: [u'1']
In [19]: [q.user.userdata.access_token for q in Question.objects.all().select_related('user__userdata')]
DEBUG (0.000) SELECT "testapp_question"."id", "testapp_question"."description", "testapp_question"."pub_date", "testapp_question"."image_url", "testapp_question"."user_id", "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined", "testapp_userdata"."id", "testapp_userdata"."user_id", "testapp_userdata"."access_token", "testapp_userdata"."profile_image_url" FROM "testapp_question" INNER JOIN "auth_user" ON ("testapp_question"."user_id" = "auth_user"."id") LEFT OUTER JOIN "testapp_userdata" ON ("auth_user"."id" = "testapp_userdata"."user_id"); args=()
Out[19]: [u'1']
Интересно отметить, что вам не нужно вызывать выбранное, связанное с ('user', 'user__userdata')
: вы можете видеть, как последний запрос извлекает данные из 3 таблиц, просто набрав 'user__userdata
':
SELECT
"testapp_question"."id", "testapp_question"."description" [...]
"auth_user"."id", "auth_user"."username" [...]
"testapp_userdata"."id", "testapp_userdata"."user_id" [...]
FROM
"testapp_question" INNER JOIN
"auth_user" ON ("testapp_question"."user_id" = "auth_user"."id") LEFT OUTER JOIN
"testapp_userdata" ON ("auth_user"."id" = "testapp_userdata"."user_id")