Votre application Django fonctionne, mais vous sentez qu'elle ralentit à mesure que les données s'accumulent ? Le coupable est souvent l'ORM. Bien que puissant, il peut générer des requêtes inefficaces si on ne lui donne pas les bonnes instructions. Voici 5 astuces pour reprendre le contrôle et accélérer drastiquement vos requêtes.

1. Le problème N+1 : Utilisez select_related et prefetch_related

C'est l'erreur la plus courante. Vous avez une liste d'articles et vous voulez afficher le nom de l'auteur pour chaque article.

  • Le code lent :

    Python

    # 1 requête pour les articles + N requêtes pour chaque auteur
    articles = Article.objects.all()
    for article in articles:
        print(article.author.name) # Une requête BDD à chaque boucle !
    
  • La solution :
    • Pour les relations ForeignKey (un-à-plusieurs), utilisez select_related. Django effectuera une jointure SQL.

      Python

      # 1 seule requête avec une jointure SQL
      articles = Article.objects.select_related('author').all()
      
    • Pour les relations ManyToManyField ou les relations inverses, utilisez prefetch_related. Django effectuera une seconde requête pour récupérer les objets liés.

      Python

      # 2 requêtes au total, peu importe le nombre d'articles
      articles = Article.objects.prefetch_related('tags').all()
      

2. Ne récupérez que ce dont vous avez besoin avec only et defer

Si votre modèle a de nombreux champs (par exemple un champ description très long) et que vous n'avez besoin que du titre, ne récupérez pas tout l'objet.

  • only() : Spécifie les champs à récupérer.

    Python

    # Ne récupère que les champs 'id' et 'title'
    titles = Article.objects.only('title')
    
  • defer() : Spécifie les champs à exclure.

    Python

    # Récupère tout sauf le contenu
    articles = Article.objects.defer('content')
    

3. Faites les calculs dans la base de données avec les annotations

Ne faites jamais de calculs en Python si la base de données peut le faire pour vous. C'est beaucoup plus rapide.

  • Le code lent (en Python) :

    Python

    articles = Article.objects.all()
    count = 0
    for article in articles:
        count += article.likes
    
  • La solution (avec Sum) :

    Python

    from django.db.models import Sum
    # Le calcul est fait par la BDD en une seule opération
    total_likes = Article.objects.aggregate(total=Sum('likes'))['total']
    

4. Utilisez values() et values_list() pour des données brutes

Si vous n'avez pas besoin des objets modèles complets mais juste des dictionnaires ou des tuples de données (par exemple pour une API ou du JavaScript), values() et values_list() sont beaucoup plus légers en mémoire.

Python

# Renvoie un QuerySet de dictionnaires
data = Article.objects.values('title', 'publication_date')

# Renvoie un QuerySet de tuples
data_list = Article.objects.values_list('title', 'publication_date')

5. Analysez vos requêtes avec Django Debug Toolbar

Comment savoir si vos requêtes sont lentes ? Installez Django Debug Toolbar. Cet outil fantastique affiche en temps réel toutes les requêtes SQL exécutées pour une page, leur durée, et détecte les requêtes dupliquées. C'est un indispensable pour tout développeur Django sérieux.

Conclusion

Maîtriser l'ORM de Django est la clé pour passer d'un développeur fonctionnel à un développeur performant. En appliquant ces techniques, vous réduirez la charge sur votre base de données, diminuerez les temps de réponse de vos pages et offrirez une expérience bien plus fluide à vos utilisateurs.