Passato attraverso le risposte già pubblicate. Ho pensato che sarebbe meglio se aggiungessi una risposta con l'esempio reale.
Supponiamo che tu abbia 3 modelli Django correlati.
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)
Qui è possibile eseguire una query sul M2
modello e sui relativi M1
oggetti utilizzando select_relation
campo e M3
oggetti utilizzando prefetch_relation
campo.
Tuttavia, come abbiamo già detto M1
, la relazione M2
è a ForeignKey
, restituisce solo 1 record per qualsiasi M2
oggetto. Lo stesso vale anche per OneToOneField
.
Ma M3
la relazione da M2
è una ManyToManyField
che potrebbe restituire qualsiasi numero di M1
oggetti.
Prendi in considerazione un caso in cui hai 2 M2
oggetti m21
, a m22
cui sono associati gli stessi 5M3
oggetti con ID 1,2,3,4,5
. Quando si recuperano M3
oggetti associati per ciascuno di tali M2
oggetti, se si utilizza Seleziona correlati, è così che funzionerà.
passi:
- Trova
m21
oggetto.
- Interroga tutti gli
M3
oggetti correlati m21
all'oggetto i cui ID sono 1,2,3,4,5
.
- Ripeti la stessa cosa per l'
m22
oggetto e tutti gli altri M2
oggetti.
Come abbiamo stessi 1,2,3,4,5
gli ID per entrambi m21
, m22
gli oggetti, se si utilizza l'opzione select_related, sta andando a interrogare il DB due volte per lo stesso ID che erano già inverosimile.
Invece se usi prefetch_related, quando tenti di ottenere M2
oggetti, prenderà nota di tutti gli ID restituiti dai tuoi oggetti (Nota: solo gli ID) durante l'interrogazione della M2
tabella e come ultimo passaggio, Django eseguirà una query alla M3
tabella con l'insieme di tutti gli ID M2
restituiti dagli oggetti. e uniscili agli M2
oggetti usando Python invece del database.
In questo modo stai interrogando tutti gli M3
oggetti solo una volta, migliorando le prestazioni.