Makina Blog
Django : améliorer les performances de prefetch_related avec l'objet Prefetch
Découvrez comment optimiser les requêtes faites par prefetch_related afin d'améliorer les performances de votre application Django.
Utiliser prefetch_related permet d'améliorer grandement les performances de ses QuerySet Django. Malheureusement cette requête à la base de données n'est pas optimale pour récupérer les objets.
C'est pourquoi il existe un objet Prefetch (depuis Django 1.7) permettant de préciser la QuerySet à utiliser par le prefetch_related.
Imaginons que nous avons les modèles suivants :
class Garniture(models.Model):
nom = models.CharField(max_length=30)
description = models.TextField()
class Pizza(models.Model):
nom = models.CharField(max_length=50)
garnitures = models.ManyToManyField(Garniture)
Ainsi nous pouvons facilement récupérer les pizzas et leur garniture avec la QuerySet suivante :
Pizza.objects.prefetch_related('garnitures').all()
Mais cela récupérera tous les attributs des garnitures. Il est inutile d'avoir le champ description si on ne l'utilise pas, étant un champ texte et potentiellement long à récupérer. Nous pourrions utiliser la méthode only pour ne sélectionner que le nom :
Garniture.objects.only('nom').all()
C'est ici que Prefetch entre en jeu, car il va nous permettre de préciser la QuerySet à utiliser :
Pizza.objects.prefetch_related(Prefetch('garnitures', queryset=Garniture.objects.only('nom').all())).all()
Et voilà, nous avons optimisé la requête effectué par prefetch_related !
Il est évidement possible d'utiliser toutes les méthodes accessible sur les QuerySet tel que defer, select_related, ou pourquoi pas un autre prefetch_related.
prefetch_related est déjà une méthode puissante permettant d'optimiser les accès à la base de données, et l'objet Prefetch nous permet d'aller encore plus loin de façon simple et intuitive.
Actualités en lien
Mise en place d’une passerelle API entre Geotrek et Cirkwi
Django
21/05/2025

Makina Corpus publie la librairie d’authentification OpenID Connect Django
Django
08/04/2025

DbToolsBundle : sortie de la version 2
Symfony
18/03/2025
