Entrambi i metodi raggiungono lo stesso scopo, per evitare query db non necessarie. Ma usano approcci diversi per l'efficienza.
L'unico motivo per utilizzare uno di questi metodi è quando una singola query di grandi dimensioni è preferibile a molte piccole query. Django utilizza la query di grandi dimensioni per creare modelli in memoria preventivamente anziché eseguire query su richiesta sul database.
select_related
esegue un join con ogni ricerca, ma estende la selezione per includere le colonne di tutte le tabelle unite. Tuttavia questo approccio ha un avvertimento.
I join hanno il potenziale di moltiplicare il numero di righe in una query. Quando si esegue un join su una chiave esterna o un campo one-to-one, il numero di righe non aumenta. Tuttavia, molti-a-molti join non hanno questa garanzia.Quindi, Django limita lo select_related
alle relazioni che non si tradurranno inaspettatamente in un massiccio join.
Il "join in python" per prefetch_related
è un po 'più allarmante quindi dovrebbe essere. Crea una query separata per ogni tabella da unire. Filtra ciascuno di questi tabella con una clausola IN WHERE, come:
SELECT "credential"."id",
"credential"."uuid",
"credential"."identity_id"
FROM "credential"
WHERE "credential"."identity_id" IN
(84706, 48746, 871441, 84713, 76492, 84621, 51472);
anziché effettuare una singola join con potenzialmente troppe righe, ciascuna tabella è diviso in una query separata.
L'esecuzione del join in python indica che il join non verrà eseguito nel database. Con un select_related, il tuo join avviene nel database e subisci solo una query del database. Con prefetch_related, eseguirai due query e quindi i risultati saranno 'uniti' dall'ORM in modo da poter digitare object.related_set –
Come nota a margine, Timmy O'Mahony può anche spiegare le loro differenze usando i risultati del database: [link] (https://timmyomahony.com/blog/misconceptions-select_related-in-django/) –