Перебрал уже выложенные ответы. Просто подумал, что будет лучше, если я добавлю ответ с реальным примером.
Допустим, у вас есть 3 модели Django, которые связаны между собой.
class M1(models.Model):
name = models.CharField(max_length=10)
class M2(models.Model):
name = models.CharField(max_length=10)
select_relation = models.ForeignKey(M1, on_delete=models.CASCADE)
prefetch_relation = models.ManyToManyField(to='M3')
class M3(models.Model):
name = models.CharField(max_length=10)
Здесь вы можете запросить M2модель и ее относительные M1объекты, используя select_relationполе, и M3объекты, используя prefetch_relationполе.
Однако, как мы уже упоминали M1, отношение from M2является a ForeignKey, оно просто возвращает только 1 запись для любого M2объекта. То же самое относится и к OneToOneField.
Но M3соотношение «S от M2это , ManyToManyFieldкоторое может возвращать любое количество M1объектов.
Рассмотрим случай, когда у вас есть 2 M2объекта m21, m22которые имеют одинаковые 5 связанных M3объектов с идентификаторами 1,2,3,4,5. Когда вы выбираете связанные M3объекты для каждого из этих M2объектов, если вы используете select related, это то, как это будет работать.
шаги:
- Найти
m21объект.
- Запросите все
M3объекты, связанные с m21объектом, чьи идентификаторы 1,2,3,4,5.
- Повторите то же самое для
m22объекта и всех других M2объектов.
Так как мы имеем одинаковые 1,2,3,4,5идентификаторы для обоих m21, m22объекты, если мы используем select_related вариант, он будет запрашивать БД дважды для одних и тех же идентификаторов , которые уже были извлечены.
Вместо этого, если вы используете prefetch_related, когда вы пытаетесь получить M2объекты, он запомнит все идентификаторы, которые ваши объекты вернули (Примечание: только идентификаторы) при запросе M2таблицы и в качестве последнего шага, Django собирается сделать запрос к M3таблице с набором всех идентификаторов, которые ваши M2объекты вернули. и присоединить их к M2объектам, используя Python вместо базы данных.
Таким образом, вы запрашиваете все M3объекты только один раз, что повышает производительность.