Le sujet d'aujourd'hui est de résoudre la curiosité : La méthode request.session.get() de Django provoque-t-elle une dégradation des performances ? 🎯

Lorsque nous développons avec Django, il est courant d'appeler plusieurs fois request.session.get('key_name'), n'est-ce pas ? Mais soudain, je me suis posé cette question.

"Si la session est finalement stockée dans la DB, chaque fois que j'appelle request.session.get(), est-ce qu'une requête DB est générée ?"

"Ou bien Django a-t-il un traitement intelligent pour éviter les requêtes supplémentaires ?"

Pour répondre à cette interrogation, j'ai plongé profondément dans le code source du SessionMiddleware de Django et j'ai confirmé par des expérimentations. 🚀

1️⃣ Comment request.session est-il créé dans Django ?

Voyons quand Django charge la session en créant l'objet de requête.

Django session management process

Nous accédons habituellement aux données de session dans une vue fonction de cette manière.

session_username = request.session.get('username')

Mais si request.session.get('username') provoque une requête DB à chaque fois, cela pourrait avoir un grand impact sur la performance, n'est-ce pas ?

🔍 Examinons l'intérieur de Django !

En fait, Django charge les données de session à l'avance via un middleware appelé SessionMiddleware lorsque la requête arrive. Dans ce processus, une requête DB est effectuée une seule fois, et ensuite, les données de session sont conservées dans l'objet de requête.

En regardant le code de Django pour le SessionMiddleware, on peut voir le traitement suivant :

class SessionMiddleware(MiddlewareMixin):
    def process_request(self, request):
        session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
        request.session = self.SessionStore(session_key)

📌 Points importants ici !

  • ✅ Nous récupérons la clé de session (session_key) à partir des request.COOKIES.
  • ✅ En appelant self.SessionStore(session_key), les données de session sont chargées une fois de la DB et stockées dans request.session.
  • ✅ Donc, même si nous appelons plusieurs fois request.session.get() dans la vue, aucune requête DB supplémentaire n’est effectuée ! 🎯

2️⃣ request.session.get() génère-t-il des requêtes DB ?

Retourons à la question principale.

"Quand on appelle request.session.get('username') dans une vue, une requête DB est-elle générée ?"

🚀 Pour faire court, appeler request.session.get() ne génère pas de requête DB supplémentaire.

La raison est simple.
✔ Django charge les données de session une fois à l’arrivée de la requête, puis les conserve dans request.session.
✔ Appeler ensuite request.session.get() signifie simplement récupérer des données déjà chargées en mémoire, donc aucune recherche DB supplémentaire n’est nécessaire.

En réalité, le moment où Django interroge la DB pour les sessions ne se produit qu'une seule fois au début de la requête. La requête SQL exécutée à ce moment est la suivante :

SELECT session_data FROM django_session WHERE session_key = 'xyz123' LIMIT 1;

  Ainsi, ✅ appeler plusieurs fois request.session.get() dans la vue ne conduit pas Django à exécuter des requêtes DB supplémentaires !
      ✅ Le chargement des données se fait une seule fois lors de la première demande !

3️⃣ Les requêtes sont-elles générées lorsque l’on utilise des données de session dans le modèle ?

"Après avoir consulté les données de session dans la vue, lorsque c’est passé au modèle, une requête DB supplémentaire est-elle générée pour les utiliser ?"

Par exemple, supposons que l’on passe les données de session comme suit dans la vue.

def my_view(request):
    session_username = request.session.get('username')  # Génère une requête DB ? ❌
    return render(request, 'my_template.html', {'session_username': session_username})

Et ensuite, utilisons-le dans le modèle comme ceci.

<p>Connecté en tant que : {{ session_username }}</p>

Dans ce cas également, aucune requête DB supplémentaire n’est générée !

session_username est une valeur déjà récupérée de request.session, donc aucune recherche DB supplémentaire n'est nécessaire lorsque Django la passe au modèle.

✔ Django gère request.session comme un cache en mémoire, ce qui permet de l’utiliser en toute sécurité dans le modèle.


4️⃣ Les données de session sont-elles sauvegardées dans la DB si elles sont modifiées ?

"Si on change les données comme request.session['username'] = 'new_value', est-ce que ça sera stocké dans la DB ?"

🚀 Dans ce cas, des modifications seront stockées dans la DB et une requête DB supplémentaire sera générée !

Si nous changeons les données de session comme suit,

request.session['username'] = 'new_value'

Django stocke les données de session modifiées dans la DB lors de l’envoi de la réponse. La requête SQL exécutée à ce moment est la suivante.

UPDATE django_session SET session_data = 'new_value' WHERE session_key = 'xyz123';

Lire une session ne génère pas de requête DB, mais modifier une session entraînera l'exécution d'une requête DB pour que Django puisse la sauvegarder.


5️⃣ Différences selon la méthode de stockage des sessions (backend)

Django permet de changer la méthode de stockage des sessions (backend). Il est important de noter que les éventuelles requêtes peuvent dépendre de la méthode de stockage.

Backend de session Description Génération de requête DB
django.contrib.sessions.backends.db Sessions basées sur la DB par défaut ✅ Générée une fois lors de la demande
django.contrib.sessions.backends.cache Sessions basées sur le cache (Redis, Memcached) ❌ Pas de requête DB
django.contrib.sessions.backends.cached_db Sessions cache + DB (interroge la DB s'il n'y a pas de cache) 🚀 Générée si pas dans le cache
django.contrib.sessions.backends.signed_cookies Sessions basées sur les cookies ❌ Pas de requête DB

🚀 Ainsi, en utilisant le backend cache ou signed_cookies, il est possible de récupérer les sessions sans requête DB. ✔ En cas de performance importante, envisager CACHED_DB_SESSION est également une bonne méthode.


🎯 Conclusion

  • ✅ Django charge les données de session via SessionMiddleware dès le début de la requête et les stocke dans l'objet request.session.
  • ✅ Donc, appeler request.session.get('username') dans la vue ne génère pas de requête DB supplémentaire.
  • Aussi, lors de l'utilisation des données de session dans le modèle, aucune requête DB supplémentaire n'est générée.
  • ✅ Cependant, lorsque la valeur de session est modifiée, Django stocke les données modifiées dans la DB lors de l'envoi de la réponse.
  • ✅ En fonction des paramètres du backend de session de Django, la génération de requêtes peut varier, donc utiliser un backend basé sur le cache (cache ou cached_db) peut réduire la charge sur la DB.

🔥 Prochain épisode : Quand l'objet request disparaît-il ?

Alors, quand l'objet request disparaît-il ?

  • Est-il en mémoire même après la fin de la requête ?

  • Est-ce nettoyé automatiquement par le système, ou devons-nous le faire nous-mêmes ?

🚀 Dans le prochain épisode, nous explorerons la durée de vie de l'objet request de Django et la gestion de la mémoire ! Restez à l'écoute ! 😃