Подтвердить что ты не робот

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')
4b9b3361

Ответ 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')) и позволяет базе данных позаботиться о втором соединении, что теоретически должно привести к несколько лучшей производительности.