Перебрал уже выложенные ответы. Просто подумал, что будет лучше, если я добавлю ответ с реальным примером.
Допустим, у вас есть 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
объекты только один раз, что повышает производительность.