Использование select_related для получения значений на расстоянии двух моделей

Допустим, у меня есть следующее:

class Model1(Model):

    field1 = ForeignKey(Model2)
    query_field = IntegerField()

class Model2(Model):
    field2 = ForeignKey(Model3)

class Model3(Model)
    field3 = SomeDesiredValue

Теперь я хочу сделать запрос к таблице Model1 и вытащить field3 из Model3. У меня вопрос по производительности select_related.

If I do

query = Model1.objects.filter(query_field=filter_paramter).select_related('field1')

Я предполагаю, что в базу данных по-прежнему попадет следующее?

query[0].field1.field2.field3

Могу ли я сделать следующее, чтобы ускорить работу?

query = Model1.objects.filter(query_field=filter_paramter).select_related('field1__field2')

person sedavidw    schedule 06.02.2015    source источник
comment
FWIW, вы можете просмотреть фактический выполняемый SQL-запрос, сказав print query.query (используя переменную в вашем примере) - здесь это связанный вопрос.   -  person Jackall    schedule 06.02.2015


Ответы (2)


Да, первый запрос приводит к двум обращениям к базе данных, а второй запрос будет обработан одним SQL-запросом с двумя ВНУТРЕННИМИ СОЕДИНЕНИЯМИ:

SELECT "app_model1"."id", "app_model1"."field1_id",
       "app_model1"."query_field", "app_model2"."id",
       "app_model2"."field2_id", "app_model3"."id",
       "app_model3"."field3"
FROM "app_model1"
INNER JOIN "app_model2" ON ( "app_model1"."field1_id" = "app_model2"."id" )
INNER JOIN "app_model3" ON ( "app_model2"."field2_id" = "app_model3"."id" )
WHERE "app_model1"."query_field" = 1 LIMIT 1
person catavaran    schedule 06.02.2015
comment
Спасибо за ответ. Быстрое уточнение, когда я использую .select_related('field1__field2'), все ли тянет с Model2? Или что ему нужно для соединения с таблицей Model3? - person sedavidw; 06.02.2015
comment
Он загружает все для моделей Model2 и Model3. Итак, obj = query.first() \n obj.field1.some_attr \n obj.field1.field2.other_attr \n obj.field1.field2.field3 - все будет обработано одним SQL-запросом. - person catavaran; 06.02.2015

class Model1(Model):

    field1 = ForeignKey(Model2, related_name="model2")
    query_field = IntegerField()

class Model2(Model):
    field2 = ForeignKey(Model3, related_name="model3")

class Model3(Model)
    field3 = SomeDesiredValue

и сделать что-нибудь подобное было бы лучше.

mdls1 = Model1.objects.filter(query_field=filter_paramter).first()

related_model3s = mdls1.field1.model3.all()

это получит все field2 из Model2 (это означает, что все связанные Model3 с Model2) Если вам нужна помощь, просто спросите :)

person Unubold Yura    schedule 06.02.2015