Passé en revue les réponses déjà publiées. Je pensais que ce serait mieux si j'ajoute une réponse avec un exemple réel.
Disons que vous avez 3 modèles Django qui sont liés.
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)
Ici, vous pouvez interroger le M2
modèle et ses M1
objets relatifs en utilisant le select_relation
champ et les M3
objets en utilisantprefetch_relation
champ.
Cependant , comme nous l' avons mentionné M1
la relation de » de M2
est ForeignKey
, elle retourne juste seulement 1 record pour tout M2
objet. La même chose s'applique pourOneToOneField
également.
Mais M3
la relation de M2
est un ManyToManyField
qui pourrait renvoyer un certain nombre deM1
objets.
Prenons un cas où vous avez 2 M2
objets m21
, m22
qui ont les mêmes 5M3
objets associés avec des ID 1,2,3,4,5
. Lorsque vous récupérez des M3
objets associés pour chacun de ces M2
objets, si vous utilisez select related, voici comment cela va fonctionner.
Pas:
- Trouver
m21
objet.
- Recherchez tous les
M3
objets liés à l' m21
objet dont les ID sont1,2,3,4,5
.
- Répétez la même chose pour l'
m22
objet et tous les autres M2
objets.
Comme nous avons les mêmes 1,2,3,4,5
identifiants pour les deux m21
,m22
objets, si nous utilisons l'option select_related, il va interroger la base de données deux fois pour les mêmes ID qui ont déjà été récupérés.
Au lieu de cela, si vous utilisez prefetch_related, lorsque vous essayez d'obtenir des M2
objets, il prendra note de tous les ID que vos objets ont renvoyés (Remarque: seuls les ID) lors de l'interrogation de la M2
table et, comme dernière étape, Django va effectuer une requête vers la M3
table avec l'ensemble de tous les ID que vos M2
objets ont renvoyés. et rejoignez-les pourM2
objets utilisant Python au lieu de la base de données.
De cette façon, vous interrogez tous les M3
objets une seule fois, ce qui améliore les performances.