Django можно выбрать связанное поле в модели, связанной с предварительной выборкой?
Предполагая их как модель джанго для простоты:
class A():
a = manytomany('B')
class B():
b = charfield()
z = foreignkey('C')
class C():
c = charfield()
Можем ли мы сделать что-то подобное, чтобы получить z
также:
foo = A.objects.get(pk = 1).prefetch_related('a').select_related('a__z')
Ответы
Ответ 1
Вам нужен только один вызов prefetch_related
:
foo = A.objects.prefetch_related('a__z').get(pk=1)
Это приведет к предварительной выборке обеих таблиц. В Django 1.7+ вы можете повысить производительность с помощью объекта Prefetch
, как в koniiiik answer.
Ответ 2
Этот ответ правильный с версиями Django до 1.7. Он генерирует три запроса: сначала извлекает экземпляр A
, затем извлекает связанные с ним экземпляры B
и, наконец, извлекает экземпляры C
связанные с экземплярами B
извлеченными во втором запросе.
До Django 1.7 это лучшее, что вы можете сделать, хотя второй запрос теоретически мог бы выбрать все объекты B
вместе со связанными объектами C
соединенными через z
ForeignKey
.
Начиная с Django 1.7, существует более продвинутый класс django.db.models.Prefetch
который позволяет вам сделать это. С Prefetch
вы можете настроить набор запросов, используемый для предварительной выборки связанных объектов, например:
foo = A.objects.prefetch_related(
Prefetch('a', queryset=B.objects.select_related('z'))
).get(pk=1)
Это приводит только к двум запросам (в отличие от трех при использовании prefetch_related('a__z')
) и позволяет базе данных позаботиться о втором соединении, что теоретически должно привести к несколько лучшей производительности.