Django select_related() vs prefetch_related() : le SQL généré

Django select_related() vs prefetch_related() : le SQL généré

select_related() ou prefetch_related() ? Les deux méthodes éliminent des requêtes N+1 dans Django, mais elles ne produisent pas du tout le même SQL. La première ajoute une jointure à la requête principale. La seconde exécute plusieurs requêtes, puis relie les objets en Python. Le bon choix dépend moins du volume de données que du type de relation traversée. Pour le comprendre, partons d’un modèle volontairement simple : from django.conf import settings from django.db import models class Post(models.Model): title = models.CharField(max_length=200) author = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="posts", ) tags = models.ManyToManyField("Tag", related_name="posts") class Comment(models.Model): post = models.ForeignKey( Post, on_delete=models.CASCADE, related_name="comments", ) body = models.TextField() is_public = models.BooleanField(default=True) author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) class Tag(models.Model): name = models.CharField(max_length=50) Depuis un Post, author désigne au maximum un utilisateur. En revanche, comments et tags peuvent contenir plusieurs objets. Cette différence de cardinalité dicte presque toujours la méthode à employer. ...

20 juillet 2026 · 8 min · Anthony
Renommer les champs Django ORM avec F() dans values()

Renommer les champs Django ORM avec F() dans values()

Quand on expose des données depuis un modèle Django vers une API ou un serializer, les noms de champs du modèle ne correspondent pas toujours à ce qu’on veut retourner. Le réflexe habituel : récupérer les instances, puis renommer en Python. Il existe une meilleure option : laisser la base de données faire le travail via F() dans values(). Le problème : les noms de champs s’imposent class Task(models.Model): name = models.CharField(...) created_at = models.DateTimeField(...) Si on veut retourner nom_tache au lieu de name, on récupère les données puis on renomme en Python, soit via une compréhension de dict, soit dans le serializer. Dans les deux cas, la transformation se fait après coup, en mémoire. ...

5 mai 2026 · 3 min · Anthony
Django Window Function vs GROUP BY : QuerySets chaînables

Django Window Function vs GROUP BY : QuerySets chaînables

Avec Django ORM, il existe deux façons d’ajouter une valeur calculée sur un ensemble de lignes : annotate() avec une agrégation classique (Max, Count, Sum…) ou annotate() avec une Window function. En surface, elles se ressemblent. En pratique, elles ont un comportement fondamentalement différent, et choisir la mauvaise peut bloquer toute la chaîne de filtrage. GROUP BY avec annotate() : des lignes qui s’écrasent Quand on combine values() et annotate() avec une agrégation, Django génère un GROUP BY en SQL. Le résultat : les lignes se regroupent, et on obtient une ligne par groupe. ...

4 mai 2026 · 4 min · Anthony
Django in_bulk() : optimiser les requêtes ORM et éviter le N+1

Django in_bulk() : optimiser les requêtes ORM et éviter le N+1

Quand on a une liste d’identifiants et qu’on veut récupérer les instances correspondantes, le réflexe habituel en Django c’est filter(pk__in=[...]). Ça marche, c’est une seule requête SQL. Mais in_bulk() est une optimisation ORM souvent ignorée : elle retourne un dictionnaire {id: instance} au lieu d’un QuerySet, ce qui change radicalement la façon d’accéder aux résultats. Là où filter() force un parcours O(n) pour retrouver un objet par son ID, in_bulk() donne un accès direct O(1). ...

4 mai 2026 · 4 min · Anthony

Newsletter

Reçois les nouveaux articles directement dans ta boite mail.

Pas de spam. Désabonnement en un clic.