El tema de curiosidad que resolveremos hoy es ¿El request.session.get() de Django provoca una disminución en el rendimiento? ¡🎯
Al desarrollar en Django, ¿cuántas veces llamamos a request.session.get('key_name')
? De repente pensé en esto.
"Si las sesiones se almacenan en la base de datos, ¿se genera una consulta a la base de datos cada vez que se llama a
request.session.get()
?""¿O Django tiene algún tipo de manejo inteligente que impide la generación de consultas adicionales?"
Para resolver esta duda, profundicé en el código fuente del SessionMiddleware de Django y lo verifiqué a través de experimentos. 🚀
1️⃣ ¿Cómo se crea request.session en Django?
Veamos cuándo Django carga la sesión al crear el objeto de solicitud.
Normalmente obtenemos los datos de la sesión en la función de vista así.
session_username = request.session.get('username')
Sin embargo, si cada vez que utilizamos request.session.get('username')
Django realiza una consulta a la base de datos, podría tener un gran impacto en el rendimiento, ¿verdad?
🔍 ¡Examinemos el interior de Django!
De hecho, Django carga los datos de la sesión de antemano a través de un middleware llamado SessionMiddleware
cuando llega la solicitud. Durante este proceso, se genera una consulta a la base de datos una sola vez, y después se mantiene el acceso a los datos de la sesión en el objeto de solicitud.
Si miramos el código de SessionMiddleware
de Django, podemos ver que se realiza el siguiente proceso.
class SessionMiddleware(MiddlewareMixin):
def process_request(self, request):
session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
request.session = self.SessionStore(session_key)
📌 ¡Punto importante aquí!
- ✅ Se obtiene la clave de sesión (
session_key
) derequest.COOKIES
. - ✅ Se llama a
self.SessionStore(session_key)
, que sólo obtiene los datos de la sesión de la base de datos una vez y los guarda en request.session. - ✅ Es decir, aunque se llame varias veces a
request.session.get()
en la función de vista, no se generarán consultas adicionales a la base de datos. 🎯
2️⃣ ¿request.session.get() genera consultas a la base de datos?
Ahora volvamos a la pregunta central.
"¿Al llamar a
request.session.get('username')
en la vista se genera una consulta a la base de datos?"
🚀 Para resumir, no se generan consultas adicionales a la base de datos al llamar a request.session.get()
.
La razón es simple.
✔ Django carga los datos de la sesión una vez cuando llega la solicitud y los guarda en request.session
.
✔ Luego, al llamar a request.session.get()
, se está accediendo a los datos que ya están cargados en la memoria, por lo que no se requiere una consulta adicional a la base de datos.
De hecho, el momento en que se consulta la base de datos para la sesión es solo una vez al inicio de la solicitud. La SQL que se ejecuta en ese momento es la siguiente.
SELECT session_data FROM django_session WHERE session_key = 'xyz123' LIMIT 1;
Es decir, ✅ incluso si se llama a request.session.get()
varias veces en la vista, Django no ejecuta consultas adicionales a la base de datos.
✅ La carga de datos desde la base de datos solo se ejecuta una vez cuando se presenta la solicitud por primera vez.
3️⃣ ¿Se genera una consulta al usar datos de sesión en la plantilla?
"¿Después de obtener los datos de la sesión en la vista y pasarlos a la plantilla, se genera otra consulta a la base de datos al utilizarlos en la plantilla?"
Por ejemplo, supongamos que pasamos los datos de sesión así en la vista.
def my_view(request):
session_username = request.session.get('username') # ¿Se genera una consulta a la DB? ❌
return render(request, 'my_template.html', {'session_username': session_username})
Y luego utilizan estos datos así en la plantilla.
<p>Conectado como: {{ session_username }}</p>
¡En este caso, tampoco se generará una consulta adicional a la base de datos!
✔ session_username
es un valor que ya se obtuvo de request.session, por lo que al Django pasarlo a la plantilla, no se requiere otra consulta a la base de datos.
✔ Django maneja request.session
como un caché en memoria, por lo que se puede usar de forma segura en la plantilla.
4️⃣ ¿Los datos de sesión se guardan en la base de datos al modificarlos?
"¿Entonces, qué pasa si modifico los datos como
request.session['username'] = 'new_value'
?"
🚀 En este caso, los cambios se guardan en la base de datos, generando una consulta adicional.
Si cambiamos los datos de la sesión como se muestra a continuación,
request.session['username'] = 'new_value'
Django guardará los datos de sesión modificados en la base de datos cuando envíe la respuesta. La SQL que se ejecuta en este momento es la siguiente.
UPDATE django_session SET session_data = 'new_value' WHERE session_key = 'xyz123';
✔ Leer la sesión no genera consultas a la base de datos, pero al modificar la sesión, Django ejecuta una consulta para guardarla en la base de datos.
5️⃣ Diferencias según el método de almacenamiento de sesión (backend)
Django permite modificar el método de almacenamiento de sesiones (backend). Es importante tener en cuenta que la generación de consultas puede variar según el backend.
Backend de sesión | Descripción | ¿Se generan consultas a la DB? |
---|---|---|
django.contrib.sessions.backends.db |
Sesiones basadas en DB por defecto | ✅ Se genera una vez al solicitar |
django.contrib.sessions.backends.cache |
Sesiones basadas en caché (Redis, Memcached) | ❌ Sin consultas a la DB |
django.contrib.sessions.backends.cached_db |
Sesiones en caché + DB (si no hay caché se consulta a la DB) | 🚀 Se genera si no está en caché |
django.contrib.sessions.backends.signed_cookies |
Sesiones basadas en cookies | ❌ Sin consultas a la DB |
🚀 Por lo tanto, utilizando backends como cache
o signed_cookies
, se pueden obtener sesiones sin consultas a la base de datos. ✔ Considerar CACHED_DB_SESSION
es una buena opción cuando el rendimiento es crítico.
🎯 Conclusión
- ✅ Django carga anticipadamente los datos de la sesión a través de
SessionMiddleware
al comienzo de la solicitud y los almacena en el objetorequest.session
. - ✅ Por lo tanto, llamar a
request.session.get('username')
desde la vista no genera consultas adicionales a la base de datos. - ✅ Al utilizar datos de sesión en la plantilla, tampoco se generan consultas adicionales a la base de datos.
- ✅ Sin embargo, cuando se modifica un valor de sesión, Django guarda el nuevo dato en la base de datos al enviar la respuesta.
- ✅ Según la configuración del backend de sesión de Django, la generación de consultas puede variar, por lo que utilizar (code>cache o
cached_db
) puede disminuir la carga en la base de datos.
🔥 Avance del siguiente episodio: ¿Cuándo desaparece el objeto request
?
Entonces, ¿cuándo desaparecerá el objeto request
?
-
¿Seguirá ocupando memoria incluso después de que la solicitud haya terminado?
-
¿El sistema lo limpiará automáticamente, o tenemos que hacerlo nosotros?
🚀 En el próximo episodio exploraremos la vida útil del objeto request
en Django y su gestión de memoria. ¡Estén atentos! 😃
Add a New Comment