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 M2modello e sui relativi M1oggetti utilizzando select_relationcampo e M3oggetti utilizzando prefetch_relationcampo.
Tuttavia, come abbiamo già detto M1, la relazione M2è a ForeignKey, restituisce solo 1 record per qualsiasi M2oggetto. Lo stesso vale anche per OneToOneField.
Ma M3la relazione da M2è una ManyToManyFieldche potrebbe restituire qualsiasi numero di M1oggetti.
Prendi in considerazione un caso in cui hai 2 M2oggetti m21, a m22cui sono associati gli stessi 5M3 oggetti con ID 1,2,3,4,5. Quando si recuperano M3oggetti associati per ciascuno di tali M2oggetti, se si utilizza Seleziona correlati, è così che funzionerà.
passi:
- Trova
m21oggetto.
- Interroga tutti gli
M3oggetti correlati m21all'oggetto i cui ID sono 1,2,3,4,5.
- Ripeti la stessa cosa per l'
m22oggetto e tutti gli altri M2oggetti.
Come abbiamo stessi 1,2,3,4,5gli ID per entrambi m21, m22gli 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 M2oggetti, prenderà nota di tutti gli ID restituiti dai tuoi oggetti (Nota: solo gli ID) durante l'interrogazione della M2tabella e come ultimo passaggio, Django eseguirà una query alla M3tabella con l'insieme di tutti gli ID M2restituiti dagli oggetti. e uniscili agli M2oggetti usando Python invece del database.
In questo modo stai interrogando tutti gli M3oggetti solo una volta, migliorando le prestazioni.