Vues matérialisées vs cache Django pour les requêtes lentes

Vues matérialisées vs cache Django pour les requêtes lentes

Le réflexe face à un endpoint de reporting lent, c’est souvent le cache. Un @cache_page, un cache.set(), et le problème disparaît… jusqu’à la prochaine expiration. Cette approche a une limite structurelle que les vues matérialisées PostgreSQL résolvent à la racine. Le problème du cache sur les endpoints analytiques Le cache Django stocke le résultat d’une vue Python. La requête SQL coûteuse s’exécute quand même à chaque expiration du cache. Pour un rapport construit sur plusieurs JOINs et agrégations, ça signifie que le premier utilisateur après chaque cache miss attend plusieurs secondes. ...

13 mai 2026 · 4 min · Anthony
Python @property : de l'encapsulation aux descripteurs

Python @property : de l'encapsulation aux descripteurs

Accéder à r.width et écrire r.width = 15 avec la syntaxe d’un attribut normal, tout en exécutant de la validation ou du calcul derrière : c’est ce que @property apporte. Et quand cette logique doit se partager entre plusieurs classes, les descripteurs entrent en jeu. @property : getters et setters sans friction @property permet d’exposer un attribut calculé ou validé avec la même syntaxe qu’un attribut simple. class Rectangle: def __init__(self, width: float, height: float): self._width = width self._height = height @property def width(self) -> float: return self._width @width.setter def width(self, value: float) -> None: if value <= 0: raise ValueError("La largeur doit être positive.") self._width = value @property def area(self) -> float: return self._width * self._height L’avantage concret : l’API publique ne change pas. Ajouter de la validation sur un attribut existant ne casse aucun code appelant. @property sans setter crée un attribut en lecture seule. @nom.deleter gère la suppression via del. ...

12 mai 2026 · 3 min · Anthony
Connascence Python : les 9 types de couplage expliqués

Connascence Python : les 9 types de couplage expliqués

Le couplage est souvent traité comme une notion vague : “c’est trop couplé” ne dit rien sur ce qu’il faut changer. La connascence propose un vocabulaire précis pour nommer les différentes formes de couplage, les comparer, et décider lesquelles réduire en priorité. Le concept est documenté en détail sur connascence.io. Trois axes pour évaluer une connascence Chaque instance de connascence s’analyse selon trois axes : Force : plus une connascence est forte, plus elle est difficile à détecter et à refactoriser. Degré : une entité couplée à des centaines d’autres est plus problématique qu’une entité couplée à deux. Localité : deux composants proches (même classe, même module) peuvent se permettre des formes plus fortes. À distance, ces mêmes formes deviennent dangereuses. Les 9 types de connascence Connascence de nom (CoN) Plusieurs composants s’accordent sur le nom d’une entité. C’est la forme la plus faible et la plus inévitable. ...

11 mai 2026 · 4 min · Anthony
Optimiser les requêtes Django ORM avec defer(), only() et Prefetch()

Optimiser les requêtes Django ORM avec defer(), only() et Prefetch()

Par défaut, Django charge tous les champs d’un modèle à chaque requête. Sur une vue liste de 50 articles, cela signifie 50 fois le contenu complet, le résumé, les métadonnées, les champs de traduction, même si on n’affiche que le titre et la date. Quatre méthodes QuerySet Django permettent de contrôler précisément ce qui est chargé : defer(), only(), values_list() et Prefetch(). Résultat : 2 requêtes SQL au lieu de N+2, avec uniquement les colonnes nécessaires. ...

8 mai 2026 · 6 min · Anthony
Django squashmigrations : nettoyer l'historique des migrations

Django squashmigrations : nettoyer l'historique des migrations

Après quelques mois de développement, il n’est pas rare d’accumuler 30, 50, voire 100 fichiers de migration sur une application Django. Chaque lancement de test qui repart d’une base vide les rejoue toutes. Chaque déploiement sur un nouvel environnement aussi. squashmigrations permet de fusionner plusieurs migrations en une seule, sans perdre la compatibilité avec les environnements déjà déployés. La commande et ce qu’elle génère La syntaxe prend une plage de migrations : ...

7 mai 2026 · 5 min · Anthony
Django select_for_update() : verrouillage de lignes et concurrence

Django select_for_update() : verrouillage de lignes et concurrence

Deux requêtes simultanées lisent le stock d’un produit, constatent qu’il en reste un, et toutes les deux valident la commande. Le stock passe à -1. Ce type de condition de course est difficile à reproduire en développement et dévastateur en production. select_for_update() est la réponse de Django : poser un verrou SQL au moment de la lecture pour garantir qu’aucune autre transaction ne peut modifier la ligne avant la fin de l’opération. ...

6 mai 2026 · 4 min · Anthony
Python __slots__ : optimiser la mémoire des instances, concrètement

Python __slots__ : optimiser la mémoire des instances, concrètement

Python crée par défaut un dictionnaire __dict__ pour chaque instance de classe. C’est flexible, pratique, mais coûteux en mémoire quand on instancie des milliers ou des millions d’objets. __slots__ est le mécanisme qui supprime ce dictionnaire et stocke les attributs dans une structure compacte. Gain typique : 40 à 60 % de mémoire en moins par instance. Ce que fait Python sans slots Sans rien déclarer, chaque instance porte son propre __dict__ : ...

6 mai 2026 · 4 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
HATEOAS : votre API REST n'est peut-être que du CRUD

HATEOAS : votre API REST n'est peut-être que du CRUD

On entend souvent “on a mis en place une API REST” dans les équipes. Mais quand on regarde les réponses JSON, il n’y a aucun lien. Juste des données brutes. Ce n’est pas du REST, c’est du CRUD exposé en HTTP. La différence tient à un principe que la plupart des développeurs ignorent : HATEOAS. Qu’est-ce que HATEOAS ? HATEOAS signifie Hypermedia As The Engine Of Application State. C’est l’une des contraintes fondamentales du REST, définie par Roy Fielding dans sa thèse de 2000 (la même qui a inventé le terme REST). ...

4 mai 2026 · 4 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

Newsletter

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

Pas de spam. Désabonnement en un clic.