Context processor en Django: Crea variables Globales en el Template - Toggle Modo Oscuro con Tailwind 4

Video thumbnail

Un context processor en Django es una función que me permite definir variables globales disponibles en todos los templates sin necesidad de pasarlas explícitamente en cada vista.

A mí me gusta explicarlo como si fuera un middleware de plantillas: no intercepta peticiones, pero sí “inyecta” información en el contexto de las vistas. Esto resulta útil cuando necesitas que ciertos datos (usuario, idioma, tema visual, etc.) estén accesibles en todas las páginas.

Diferencia entre context processors y middleware

  • Aunque se parecen en concepto, no son lo mismo:
  • Middleware: trabaja a nivel de request/response.
  • Context processor: actúa al momento de renderizar un template.

Context processors por defecto en Django

Django ya incluye algunos listos para usar, como:

  • django.template.context_processors.request → añade el objeto request.
  • django.contrib.auth.context_processors.auth → añade info del usuario autenticado.
  • django.contrib.messages.context_processors.messages → inyecta mensajes flash.

Cómo crear un context processor personalizado

El context processor en Django funciona como un middleware para los templates y define variables globales que estarán disponibles en todos los templates. Primero, creo un archivo context_processors.py dentro de mi aplicación:

djangoshopping/<app>/context_processors.py

def theme(request):
   current_theme = request.session.get('theme', 'light') # 'light' es el valor por defecto
   return {'theme': current_theme}

En este caso leemos el valor desde la sesión. Si no existe, devolvemos un valor por defecto, por ejemplo "light".
Luego registramos este context processor en la configuración de TEMPLATES para que Django lo utilice:

settings.py

TEMPLATES = [
    {
        ***
        'OPTIONS': {
            'context_processors': [
                ***
                # custom context processors
                'user.context_processors.theme',
            ],
        },
    },
]

Acceso a las variables en los templates

Una vez registrado, ya puedo usar la variable theme en cualquier template sin pasarla desde la vista.

Implementación del Toggle de Tema claro/oscuro

Lo siguiente que vamos a hacer es implementar el toggle para poder seleccionar entre modo claro y modo oscuro en Tailwind 4 con Django, que recordemos que instalamos de antes mediante Django Template.

El context processor devuelve siempre la variable theme según la sesión del usuario. Esto asegura que la preferencia se mantenga aunque navegue por toda la web.

Vista Basada en Clases

Por ejemplo, tengo el modo oscuro, luego el modo claro, recargo la página y ahí lo ves reflejado. Eso es lo que vamos a implementar.

Definimos una vista basada en clases que recibe peticiones POST:

djangoshopping\user\views.py

from django.shortcuts import redirect
from django.views import View
class ToggleThemeView(View):
    def post(self, request, *args, **kwargs):
        theme = request.POST.get('theme')
        if theme in ['light', 'dark']:
            request.session['theme'] = theme
        return redirect(request.META.get('HTTP_REFERER', 'user.profile'))

¿Por qué POST? Porque estamos actualizando datos (en este caso, la sesión con el tema). La vista recibe la petición, verifica que el valor esté dentro de lo permitido, lo asigna a la sesión y luego recarga la página.

Configuramos la ruta:

djangoshopping\djangoshopping\urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('toggle-theme/', ToggleThemeView.as_view(), name='toggle_theme'),
***    

Template con select y Tailwind para cambiar el tema

Para el proceso de actualizar, lo hacemos mediante formulario:

<form action="{% url 'toggle_theme' %}" method="post" class="text-gray-700 font-semibold mb-1">
    {% csrf_token %}
    <select name="theme" class="w-full p-2 border border-gray-300 rounded-md form-select">
        <option value="light" {% if theme == 'light' %}selected{% endif %}>
            {% trans "Choose your theme" %}: {% trans "Light" %}
        </option>
        <option value="dark" {% if theme == 'dark' %}selected{% endif %}>
            {% trans "Choose your theme" %}: {% trans "Dark" %}
        </option>
    </select>
    <button type="submit">Send</button>
</form>

Incluye un select con dos opciones: modo claro y modo oscuro. 
Cada vez que cambio el valor, se guarda en la sesión y el context processor lo hace disponible en todos los templates. Al recargar, el tema se refleja de inmediato.

Y ahora, lo utilizamos en la plantilla maestra; por ejemplo:

master.html

<html lang="en" class="{{ theme }}">

Uso de la Variable "theme" definida en el context processors

Seguramente te preguntas cómo utilizamos la variable theme en cualquier parte de la aplicación. Esto se logra con un context processor, que nos permite inyectar variables globales en todos los templates, en este ejemplo, el uso de la variable theme.

Mejores prácticas y errores comunes

Con el tiempo fui aprendiendo algunas lecciones que merece la pena compartir:

  • Usar POST para actualizar datos de sesión
    • Aunque parezca tentador usar GET, lo correcto es usar POST para respetar las buenas prácticas HTTP.
  • No olvidar registrar el context processor en settings.py
    • Es el error más común: definir la función pero no añadirla en TEMPLATES. Sin esto, nunca funcionará.
  • Evitar lógica compleja en el context processor
    • El objetivo es inyectar datos simples y rápidos de calcular. Si incluyes lógica pesada, ralentizarás el renderizado de todas las páginas.

Preguntas frecuentes sobre context processors en Django

  • ¿Cómo probar si funciona un context processor?
    • Puedes arrancar el servidor y verificar en cualquier template si la variable aparece. Otra opción es usar RequestFactory en los tests para simular un request.
  • ¿Se pueden usar variables de sesión en un context processor?
    • Sí, como hice yo en el ejemplo del tema claro/oscuro. De hecho, es uno de los usos más comunes.
  • ¿Qué otros usos prácticos tienen los context processors?
    • Mostrar un carrito de compras en todas las páginas.
    • Inyectar configuraciones globales (logo, idioma, metadatos).
    • Variables de tracking o analítica.

Conclusión

Con esta implementación ya tenemos un sistema de cambio de tema (claro/oscuro) controlado por sesión y disponible en todos los templates mediante un context processor.
El estilo lo ajustaremos más adelante, pero la base funcional ya está lista.

Los context processors en Django son una herramienta sencilla pero muy potente. En mi caso, los utilicé para implementar un sistema de tema claro/oscuro que se guarda en la sesión y está disponible en todos los templates gracias a esta técnica.

Si quieres ir más allá, te recomiendo experimentar con otros casos prácticos como el carrito de compras o la personalización de la UI según el perfil del usuario.

Acepto recibir anuncios de interes sobre este Blog.

Descubre qué son los context processors en Django, cómo crearlos y usarlos para inyectar variables globales en tus templates. Te muestro un ejemplo práctico con un toggle de tema claro/oscuro usando sesiones y Tailwind, además de mejores prácticas, errores comunes y FAQs para que domines esta herramienta.

| 👤 Andrés Cruz

🇺🇸 In english