Presentación

Quieres crear una aplicación web.

Necesitas usuarios.

Una base de datos.

Permisos.

Formularios.

Sesiones.

Un espacio de administración.

Emails.

Páginas.

URLs.

Y protecciones contra unas cuantas maneras creativas de convertir Internet en un incendio.

En este punto aparecen dos filosofías.

La primera consiste en elegir una pequeña biblioteca y ensamblar progresivamente cada pieza.

La segunda dice:

«Estos problemas aparecen en casi todas las aplicaciones. ¿Por qué no empezar con una caja que ya viene llena?»

Django pertenece claramente a la segunda escuela.

Un framework que prefiere ofrecer demasiado antes que demasiado poco

Django es un framework web open source escrito en Python.

Proporciona directamente gran parte de la infraestructura necesaria para una aplicación web clásica:

ORM;

migraciones de base de datos;

routing de URLs;

vistas;

templates;

formularios;

autenticación;

usuarios, grupos y permisos;

sesiones;

interfaz de administración;

internacionalización;

gestión de archivos estáticos;

email;

middleware;

cache;

herramientas de testing;

seguridad;

comandos de administración.

El sitio oficial resume esta filosofía con una expresión que se ha vuelto casi inseparable del proyecto:

«batteries included».

El objetivo no es resolver todos los problemas posibles.

Consiste en evitar que cada nuevo proyecto tenga que reconstruir las mismas bases desde cero.

Django no te da solamente los ladrillos. Ya te propone una manera razonable de construir la casa.

Nacido en una redacción, no en un laboratorio abstracto

Django apareció a principios de los años 2000 dentro del periódico Lawrence Journal-World, en Estados Unidos.

Desarrolladores como Adrian Holovaty y Simon Willison trabajaban entonces en varios sitios de noticias y necesitaban producir rápidamente aplicaciones web alimentadas por grandes cantidades de datos.

Las mismas necesidades regresaban.

Modelos.

Administración.

Publicación.

URLs.

Formularios.

Bases de datos.

En lugar de resolver los mismos problemas una y otra vez, las herramientas internas comenzaron a formar un framework coherente.

Django se publicó como open source en 2005.

Su nombre rinde homenaje al guitarrista Django Reinhardt.

La historia explica muchas de sus decisiones.

Django no fue diseñado como una demostración de minimalismo arquitectónico.

Fue construido para una situación mucho más concreta:

hay que entregar una aplicación seria, con datos reales, personas reales utilizándola y un plazo que no tiene absolutamente ninguna intención de negociar.

Ese contexto sigue apareciendo en el lema oficial:

«The web framework for perfectionists with deadlines.»

Un framework Python completo, no un generador de sitios

Django no crea automáticamente una aplicación por ti.

No sustituye HTML.

No sustituye CSS.

No sustituye JavaScript.

No sustituye PostgreSQL.

Y tampoco transforma mágicamente una idea en un SaaS rentable antes de comer.

Proporciona una estructura del lado del servidor.

Una aplicación Django recibe peticiones HTTP, ejecuta la lógica Python necesaria, puede comunicarse con una base de datos y después devuelve una respuesta:

HTML;

JSON;

archivo;

redirección;

stream;

u otra respuesta HTTP.

El frontend puede renderizarse directamente con los templates de Django.

O estar completamente separado mediante React, Vue, Svelte o una aplicación móvil que consume una API.

Django puede utilizarse, por tanto, como framework full-stack tradicional.

Pero también como backend.

MTV en lugar de MVC

Django suele compararse con el modelo MVC — Model View Controller.

Su terminología histórica es ligeramente diferente.

Se habla más bien de:

Model: los datos y su representación;

Template: la presentación;

View: la lógica que recibe la petición y decide la respuesta.

El papel que otros frameworks llaman a veces «controller» está repartido en parte entre el routing de URLs y las vistas de Django.

Por eso se encuentra a menudo el término MTV — Model Template View.

La diferencia de vocabulario importa menos que la idea que representa:

separar suficientemente las responsabilidades para que la aplicación pueda crecer sin convertirse inmediatamente en un único archivo app.py de 9.000 líneas.

Un proyecto compuesto por aplicaciones

Django suele distinguir el project de las apps.

El proyecto contiene la configuración global.

Las apps agrupan funcionalidades más concretas.

Por ejemplo:

miproyecto/
├── accounts/
├── articles/
├── billing/
├── dashboard/
└── miproyecto/

articles puede gestionar el contenido.

accounts los usuarios.

billing los pagos.

dashboard las vistas internas.

Esta estructura favorece una organización modular.

Una app Django bien diseñada incluso puede reutilizarse en varios proyectos.

Eso no significa que haya que transformar cada función en una aplicación independiente.

Como siempre, la arquitectura empieza a ponerse extraña cuando se convierte en una competición de fragmentación.

Pero el mecanismo ofrece una frontera útil.

Django 6.1 hoy

A 8 de agosto de 2026, la última versión oficial es Django 6.1, publicada el 5 de agosto de 2026.

Es oficialmente compatible con:

Python 3.12;

Python 3.13;

Python 3.14.

Django 6.1 continúa especialmente el trabajo reciente alrededor del rendimiento del ORM, la administración, Content Security Policy, las tareas, el email y varios componentes internos.

Pero «última versión» no significa necesariamente «mejor versión para cada proyecto».

La rama Django 5.2 es una versión LTS — Long-Term Support.

Recibe soporte extendido hasta abril de 2028.

Django 6.1, por su parte, es una release funcional más reciente cuyo soporte extendido está previsto hasta diciembre de 2027.

Para un proyecto nuevo, la decisión puede ser:

6.1 para las funciones recientes

o

5.2 LTS para una ventana de mantenimiento más larga.

En abril de 2027, Django 6.2 debería convertirse a su vez en la próxima rama LTS.

Funcionalidades

El ORM: trabajar con los datos como objetos Python

Una de las piezas centrales de Django es su ORM — Object-Relational Mapper.

Se puede definir un modelo:

from django.db import models


class Article(models.Model):
    title = models.CharField(max_length=200)
    published = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)

Django utiliza después esta definición para trabajar con la base de datos.

Crear:

Article.objects.create(
    title="Entender Django",
    published=True,
)

Buscar:

articles = Article.objects.filter(published=True)

Ordenar:

articles = Article.objects.order_by("-created_at")

La idea consiste en manipular los datos mediante una API Python en lugar de escribir SQL directamente para cada operación.

Esto acelera enormemente el desarrollo.

Pero el ORM no hace desaparecer la base de datos.

Debajo de los objetos Python siguen existiendo:

tablas;

índices;

joins;

restricciones;

transacciones;

consultas;

planes de ejecución.

La comodidad del ORM es enorme.

Se vuelve todavía mejor cuando se comprende lo que produce.

Migraciones: hacer evolucionar el esquema junto con el código

Un modelo cambia.

Aparece un campo.

Otro se vuelve nullable.

Se añade una relación.

Django puede generar una migración:

python manage.py makemigrations

Y después aplicarla:

python manage.py migrate

Las migraciones describen la evolución del esquema de la base de datos.

Pueden versionarse con Git.

Un equipo puede compartir así no solamente su código, sino también la historia estructural de sus datos.

Hoy parece casi algo normal.

Hasta que imaginamos tener que gestionar manualmente los cambios SQL de quince desarrolladores en varios entornos.

Entonces las migraciones se vuelven de repente muy simpáticas.

La administración: probablemente la función que vende Django en cinco minutos

Se define un modelo.

Se registra en el admin.

Y Django puede generar una interfaz de gestión.

Lista.

Búsqueda.

Filtros.

Creación.

Modificación.

Eliminación.

Relaciones.

Permisos.

Todo a partir de los modelos.

from django.contrib import admin
from .models import Article

admin.site.register(Article)

Después, la administración puede personalizarse en profundidad.

Columnas.

Filtros.

Acciones.

Formularios.

Relaciones inline.

Búsqueda.

Permisos.

Templates.

Es una función extraordinaria para:

back-offices;

CMS internos;

catálogos;

equipos editoriales;

herramientas de negocio;

bases de datos administrables.

Pero hay que comprender para qué sirve.

Django Admin es una interfaz para las personas que administran los datos. No es automáticamente el frontend que deben ver tus usuarios.

Confundir ambos conduce rápidamente a intentar transformar una excelente interfaz interna en un producto para el gran público con suficiente CSS como para empezar a negociar directamente con el destino.

Autenticación, usuarios y permisos

Django posee su propio sistema de autenticación.

Incluye, entre otras cosas:

usuarios;

contraseñas;

hashing;

grupos;

permisos;

sesiones;

login;

logout;

restablecimiento de contraseña;

backends de autenticación personalizables.

Los modelos pueden recibir automáticamente los permisos clásicos:

add

change

delete

view

Después se pueden asignar esos permisos a un usuario o a un grupo.

Esto proporciona una base sólida para muchas aplicaciones de negocio.

Django también puede ampliarse para funcionar con sistemas de autenticación externos o modelos de usuario personalizados.

Y un consejo vuelve regularmente en el ecosistema:

si probablemente el proyecto necesitará un usuario personalizado, es mejor definirlo pronto.

Cambiar el modelo de usuario cuando quince aplicaciones y tres años de migraciones ya lo referencian es técnicamente posible.

Como mover una cocina después de terminar el edificio.

Formularios y validación

Los formularios web tienen la extraordinaria capacidad de parecer sencillos hasta el momento en que realmente hay que gestionar:

validación;

mensajes de error;

tipos;

valores obligatorios;

archivos;

seguridad;

redisplay de los datos;

relaciones con los modelos.

Django dispone de un sistema de Forms y ModelForms.

from django import forms
from .models import Article


class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = ["title", "published"]

Un formulario puede:

validar las entradas;

convertir tipos;

producir errores estructurados;

generar campos HTML;

conectarse directamente con un modelo.

Es menos espectacular que un nuevo framework JavaScript con una homepage animada.

Pero extremadamente útil cuando hay que construir el formulario número setenta y dos de una aplicación de negocio.

Routing de URLs

Django posee un router explícito.

from django.urls import path
from . import views

urlpatterns = [
    path("articles/", views.article_list, name="article-list"),
]

Una URL está asociada a una vista.

Los patterns pueden agruparse por app.

Las rutas pueden recibir nombres.

Los templates y el código pueden después generar URLs sin copiar rutas hardcoded por todas partes.

Es una pequeña abstracción.

Pero evita muchos enlaces rotos cuando la aplicación evoluciona.

Vistas basadas en funciones o en clases

Una vista Django puede ser una simple función:

def home(request):
    return render(request, "home.html")

O una class-based view.

Django proporciona numerosas vistas genéricas para operaciones clásicas:

lista;

detalle;

creación;

modificación;

eliminación;

redirección;

templates.

Las class-based views pueden eliminar mucha repetición.

También pueden generar ese momento particular en el que se recorren cinco niveles de herencia para comprender por qué se está llamando a un método.

Por eso ambos estilos son útiles.

La mejor vista suele ser aquella cuyo comportamiento el equipo todavía puede comprender seis meses después.

Templates: producir HTML del lado del servidor

Django posee su propio motor de templates.

{% for article in articles %}
    <article>
        <h2>{{ article.title }}</h2>
    </article>
{% endfor %}

Es compatible con:

variables;

bucles;

condiciones;

herencia;

inclusiones;

filtros;

tags personalizados.

Desde Django 6.0, el lenguaje de templates también dispone de template partials integrados para definir y reutilizar con mayor facilidad pequeños fragmentos.

Esta evolución acompaña el renovado interés por arquitecturas modernas del lado del servidor donde Django se combina con HTMX, Alpine.js o pequeñas capas JavaScript en lugar de una SPA completa.

Quizá el viejo renderizado del lado del servidor no estaba muerto.

Solo estaba echándose una larga siesta de marketing.

Una interfaz de administración que sigue los modelos

El admin no se limita a mostrar tablas.

Comprende las relaciones entre modelos.

Foreign keys.

Many-to-many.

Permisos.

Filtros.

Búsqueda.

Acciones.

Widgets.

Puede proporcionar en pocos minutos una herramienta interna que habría requerido varios días de desarrollo específico.

Probablemente sea una de las manifestaciones más puras de la filosofía Django:

escribir una sola vez la estructura del dominio y dejar después que distintas partes del framework la aprovechen.

El modelo alimenta el ORM.

Las migraciones.

Los formularios.

El admin.

Los permisos.

Esta coherencia reduce enormemente la duplicación.

Seguridad integrada

Django tiene desde hace mucho tiempo una reputación seria en seguridad web.

El framework ofrece protecciones frente a varias categorías comunes de ataques, entre ellas:

inyecciones SQL mediante el ORM parametrizado;

Cross-Site Request Forgery — CSRF;

Cross-Site Scripting — XSS en el motor de templates cuando el escaping se utiliza normalmente;

clickjacking;

contraseñas almacenadas con algoritmos de hash apropiados;

sesiones seguras;

headers y ajustes HTTPS.

Django 6.0 añadió soporte integrado de Content Security Policy — CSP.

Una aplicación puede ahora configurar políticas CSP y sus headers directamente a través del framework.

Eso no significa, evidentemente:

«Django es seguro, así que puedo dejar de pensar en seguridad».

Un desarrollador siempre puede:

desactivar CSRF;

inyectar HTML marcado como seguro;

escribir SQL raw incorrecto;

exponer una SECRET_KEY;

dejar DEBUG = True en producción;

configurar mal HTTPS.

El framework proporciona barreras de seguridad.

No puede impedir que alguien las desmonte.

Middleware: intervenir en el ciclo petición-respuesta

El middleware permite insertar una capa alrededor del procesamiento de las peticiones.

Puede servir para:

autenticación;

sesiones;

seguridad;

compresión;

logs;

headers;

localización;

medición de rendimiento;

lógica específica del proyecto.

Una petición atraviesa varios middleware antes de llegar a la vista.

Después, la respuesta vuelve a atravesar la cadena.

Es una arquitectura muy práctica para comportamientos transversales.

Siempre que el middleware no se convierta en el cajón donde se esconde toda la lógica que no sabíamos dónde colocar.

Sesiones, mensajes y cookies

Django incluye una infraestructura de sesiones.

Una aplicación puede asociar datos temporales a un usuario entre varias peticiones.

El framework también posee un sistema de mensajes que permite, por ejemplo, mostrar:

«Artículo creado»

«Pago fallido»

«Perfil actualizado»

después de una redirección.

Son pequeñas funciones.

Pero la filosofía «batteries included» se mide precisamente con este tipo de detalles.

Una aplicación real está formada por cientos de pequeñas necesidades poco espectaculares.

Django intenta haber resuelto ya muchas de ellas.

Email

Django proporciona una abstracción para enviar emails.

SMTP.

Backends de desarrollo.

Backends personalizados.

Mensajes HTML.

Archivos adjuntos.

Desde Django 6.1, el sistema evoluciona hacia una nueva configuración MAILERS capaz de gestionar varios backends de email.

Podemos imaginar:

un backend transaccional;

un backend marketing;

un backend específico para determinadas notificaciones.

Otra función que podríamos desarrollar nosotros mismos.

Y otra razón para quizá no hacerlo.

Tareas en segundo plano

Django 6.0 introdujo un Tasks framework.

Proporciona una abstracción para:

definir una tarea;

validarla;

colocarla en una cola;

gestionar su resultado.

Por ejemplo, un email o un procesamiento de datos puede salir del ciclo HTTP principal.

Pero existe un matiz importante:

Django no proporciona por sí mismo el worker de producción que ejecuta estas tareas.

Los backends integrados están destinados principalmente al desarrollo y los tests.

La ejecución real necesita una infraestructura externa adecuada.

Por tanto, el framework proporciona ahora el contrato.

No toda la fábrica.

Celery, Dramatiq u otros sistemas pueden seguir teniendo un lugar según el proyecto.

Síncrono y asíncrono

Django ha sido históricamente un framework síncrono basado en WSGI.

Ahora posee un soporte creciente para ASGI y código asíncrono.

Las vistas pueden ser async.

Algunas operaciones disponen de versiones asíncronas.

El ecosistema continúa avanzando en esa dirección.

Pero Django no se convirtió de la noche a la mañana en un framework completamente async en todas sus capas.

Algunas partes siguen siendo síncronas.

También algunas bibliotecas de terceros.

Y llamar a código bloqueante dentro de una vista async sigue siendo una excelente forma de construir una arquitectura muy moderna que espera con gran eficiencia.

Varias bases de datos oficialmente soportadas

Django soporta oficialmente:

PostgreSQL

MariaDB

MySQL

Oracle

SQLite

SQLite resulta especialmente práctica para empezar.

No necesita un servidor separado.

Para una aplicación importante, la documentación de Django recomienda generalmente desarrollar con el mismo motor previsto para producción.

PostgreSQL es hoy una opción extremadamente frecuente dentro del ecosistema Django.

El framework posee además funcionalidades adicionales específicas para PostgreSQL mediante django.contrib.postgres.

Cache

Django posee una abstracción de cache.

Según la infraestructura, la cache puede almacenar:

resultados costosos;

páginas;

fragmentos;

sesiones;

datos consultados con frecuencia.

Puede funcionar con varios backends.

Una aplicación puede así empezar de forma sencilla y añadir más cache cuando la carga realmente lo necesite.

Lo cual suele ser preferible a construir el lunes por la mañana una arquitectura de cache distribuida destinada a los doce usuarios previstos para el viernes.

Internacionalización y localización

Django dispone desde hace mucho tiempo de herramientas para:

traducir strings;

gestionar varios idiomas;

adaptar formatos de fecha;

trabajar con zonas horarias;

generar catálogos de traducción;

detectar o seleccionar un idioma.

Para un proyecto multilingüe, esta infraestructura evita transformar las traducciones en una colección artesanal de condiciones dispersas por los templates.

Comandos de gestión

El archivo manage.py da acceso a numerosos comandos:

python manage.py runserver
python manage.py migrate
python manage.py createsuperuser
python manage.py collectstatic
python manage.py test
python manage.py check

Los proyectos también pueden crear sus propios comandos.

Es extremadamente útil para:

imports;

mantenimiento;

migración de datos;

automatización;

tareas administrativas;

scripts internos.

En lugar de crear veinte scripts aislados que nadie recuerda si todavía deben utilizarse, se pueden integrar estas operaciones directamente en el entorno Django.

Casos de uso

Construir una aplicación de negocio rica en datos

Usuarios.

Clientes.

Pedidos.

Documentos.

Permisos.

Estados.

Historial.

Administración.

Búsqueda.

Relaciones.

Django se encuentra especialmente cómodo cuando el núcleo de la aplicación se parece a esto.

Se definen los modelos.

Se construyen las reglas de negocio.

El ORM gestiona los datos.

El admin proporciona rápidamente un back-office.

La autenticación controla los accesos.

Los formularios gestionan las entradas.

Esta combinación hace que Django sea extremadamente eficaz para aplicaciones de gestión.

Construir un CMS o una plataforma editorial

La propia historia de Django procede de la publicación web.

El framework sigue siendo natural para:

artículos;

categorías;

autores;

medios;

traducciones;

permisos editoriales;

workflow de publicación;

SEO;

back-office.

Django por sí mismo no es un CMS listo para usar.

Pero constituye una excelente base para construir uno.

Proyectos como Wagtail muestran, además, hasta dónde puede llevarse esta arquitectura.

Crear un SaaS

Una aplicación SaaS suele tener:

cuentas;

equipos;

permisos;

suscripciones;

dashboards;

emails;

base de datos;

back-office;

API;

tareas en segundo plano.

Django ya proporciona una gran parte de esta fontanería.

Queda por construir aquello que realmente diferencia el producto.

Que, en teoría, era precisamente la idea.

Construir rápidamente una herramienta interna

Una empresa necesita gestionar:

inventario;

proyectos;

solicitudes;

clientes;

documentos;

catálogos;

validaciones.

La aplicación no necesita necesariamente un frontend espectacular.

Necesita funcionar.

Django Admin se vuelve entonces especialmente formidable.

Algunos modelos.

Algunos permisos.

Algunas personalizaciones.

Y el equipo ya dispone de una interfaz interna utilizable.

No necesariamente la que ganará un premio de diseño.

Pero sí la que puede impedir que veinte personas sigan gestionando la empresa con tabla_final_2026_v12_corregida.xlsx.

Crear una API

Django puede servir perfectamente como backend API.

Puede devolver JSON directamente.

Pero Django core no proporciona por sí solo toda la experiencia de un framework REST especializado.

Para ello, el ecosistema utiliza ampliamente:

Django REST Framework

o soluciones como:

Django Ninja.

Django REST Framework añade, entre otras cosas:

serializers;

viewsets;

permisos API;

autenticación;

paginación;

browsable API;

herramientas REST.

Django se convierte entonces en la capa de:

modelos;

ORM;

usuarios;

business logic;

admin;

infraestructura.

Y DRF expone esa lógica al frontend o a las aplicaciones móviles.

Backend de una aplicación frontend separada

Una aplicación React, Vue o Svelte puede ignorar completamente los templates de Django.

El frontend solicita:

/api/articles/

Django comprueba el usuario.

Consulta PostgreSQL.

Aplica los permisos.

Devuelve JSON.

En este escenario, Django desempeña el papel de backend estructurado.

Su admin puede seguir sirviendo al equipo interno mientras que el público utiliza una interfaz completamente diferente.

Es una de sus ventajas más prácticas.

El frontend y el back-office no tienen por qué ser la misma aplicación visual.

Construir con muy poco JavaScript

Django también puede seguir el enfoque contrario.

Templates del lado del servidor.

Formularios Django.

HTMX para algunas interacciones.

Alpine.js para determinados comportamientos locales.

Se pueden crear así aplicaciones muy interactivas sin necesidad de construir una SPA completa.

Este enfoque está recuperando interés.

Puede reducir:

complejidad del build frontend;

duplicación de validaciones;

gestión de estado;

API internas innecesarias;

número de dependencias.

No todo necesita dos aplicaciones separadas comunicándose mediante JSON para mostrar un botón «Editar».

Construir un prototipo que deba sobrevivir

Existen frameworks excelentes para crear una demostración en pocos minutos.

El problema empieza cuando la demostración se convierte en el producto.

Django posee una cualidad particular:

se puede empezar bastante rápido manteniendo unas bases capaces de soportar un proyecto mucho más grande.

Modelos.

Migraciones.

Tests.

Apps.

Permisos.

Settings.

Admin.

La estructura ya existe.

El prototipo puede evolucionar sin exigir inmediatamente una reescritura completa.

Siempre que, evidentemente, el prototipo no haya convertido views.py en un diario íntimo de 7.000 líneas.

Opinión de PANACHES

Django posee una cualidad que se ha vuelto casi inusual en el desarrollo moderno:

asume que tiene opiniones.

Una aplicación tiene modelos.

Un sistema de settings.

Apps.

Migraciones.

URLs.

Templates.

Convenciones.

Un admin.

Django no te mira en el primer lanzamiento diciendo:

«Aquí tienes una función HTTP. Buena suerte con el resto».

Propone un marco.

Su verdadera fuerza es la coherencia entre las piezas

Tomado por separado, casi cada componente de Django tiene una alternativa.

¿ORM?

SQLAlchemy.

¿Templates?

Jinja.

¿Forms?

Existen otras bibliotecas.

¿Auth?

Más alternativas.

¿Admin?

Packages especializados.

¿Routing?

Fácil de encontrar.

La potencia de Django no viene, por tanto, de que ninguna otra tecnología sepa hacer estas cosas.

Viene de que todas estas piezas han sido diseñadas para funcionar juntas.

El modelo alimenta las migraciones.

El ORM utiliza los modelos.

Los ModelForms utilizan los modelos.

El admin utiliza los modelos.

Los permisos utilizan los modelos.

Esta continuidad reduce enormemente el número de decisiones y conexiones manuales.

¿Batteries included o dependencias impuestas?

Todo depende del punto de vista.

Para algunos desarrolladores:

«genial, todo está aquí».

Para otros:

«¿por qué está ya todo aquí?»

Esta es exactamente la frontera entre Django y los microframeworks.

Con Flask se eligen más componentes.

Con FastAPI se obtiene una excelente base moderna para construir APIs y después se ensambla el resto según las necesidades.

Con Django, muchas decisiones ya están tomadas.

Esta restricción puede acelerar enormemente un proyecto.

También puede parecer excesiva si la aplicación solo necesita tres endpoints JSON.

Django vs FastAPI

La comparación aparece a menudo.

Pero ambas herramientas no parten exactamente del mismo lugar.

FastAPI destaca en la construcción de APIs modernas, especialmente gracias a las anotaciones de tipos de Python, OpenAPI y su orientación async.

Django apunta a un perímetro más amplio:

datos;

auth;

admin;

templates;

sesiones;

formularios;

migraciones;

aplicaciones de negocio completas.

Si el objetivo es:

«quiero ocho endpoints API extremadamente limpios»

FastAPI puede resultar natural.

Si el objetivo pasa a ser:

«usuarios, roles, admin, treinta modelos, formularios, emails, CMS, back-office y una API»

Django empieza a mostrar por qué lleva más equipaje.

Django vs Flask

Flask adopta casi la filosofía opuesta.

Un núcleo pequeño.

Mucha libertad.

Añadir lo que el proyecto necesite.

Esto puede resultar excelente para:

pequeños servicios;

prototipos;

aplicaciones específicas;

equipos que quieren elegir con precisión cada componente.

Django prefiere proporcionar una arquitectura más completa.

Por tanto, la pregunta no es:

«¿cuál es mejor?»

Sino:

«¿cuántas decisiones queremos tomar nosotros mismos?»

Django vs Laravel o Ruby on Rails

Laravel y Ruby on Rails probablemente estén más cerca filosóficamente de Django.

Frameworks full-stack.

ORM.

Migraciones.

Convenciones.

Ecosistemas importantes.

Desarrollo rápido.

Rails ha llevado históricamente muy lejos la convention over configuration.

Laravel se beneficia de un ecosistema PHP enorme y de una experiencia de desarrollo muy trabajada.

Django, por su parte, tiene la ventaja de vivir dentro del universo Python.

Y ese universo se ha vuelto gigantesco.

Data.

Scripts.

IA.

Automatización.

Procesamiento de imágenes.

Investigación.

Django puede conectarse de forma natural con muchas bibliotecas Python sin crear una segunda stack tecnológica.

El admin sigue siendo un superpoder

Es fácil subestimar Django Admin porque no es especialmente espectacular.

Después llega un proyecto con cuarenta modelos.

Personas no técnicas necesitan modificar los datos.

Se necesitan permisos.

Filtros.

Búsqueda.

Acciones.

Relaciones.

Y de repente el equipo comprende que desde el primer día ya disponía de un back-office ampliamente funcional.

Probablemente sea una de las funciones que produce una de las mejores relaciones entre:

líneas de código escritas / trabajo realmente evitado.

Django no es viejo. Es maduro.

Django existe desde hace más de veinte años.

En tecnología, eso puede provocar un reflejo extraño:

«Si existe desde hace tanto tiempo, seguro que hay algo más moderno».

A veces sí.

Pero «más reciente» y «mejor» no son sinónimos.

Django posee:

años de correcciones;

una documentación enorme;

convenciones estabilizadas;

un ecosistema maduro;

prácticas de seguridad sólidas;

migraciones probadas;

una comunidad mundial;

empresas que lo utilizan en producción desde hace mucho tiempo.

La madurez produce menos screenshots emocionantes que un nuevo framework publicado el jueves.

A menudo produce más noches tranquilas.

Pero Django debe seguir evolucionando

La web de 2026 ya no es la de 2005.

Async.

APIs.

SPAs.

HTMX.

WebSockets.

Background tasks.

CSP.

Type hints.

IA.

Arquitecturas distribuidas.

Django ha tenido que integrar progresivamente estos cambios.

Las versiones 6.0 y 6.1 muestran precisamente este movimiento:

CSP integrada;

template partials;

framework de tareas;

mejoras async;

evolución del email;

nuevas optimizaciones ORM.

El equilibrio es delicado.

Moverse demasiado rápido rompería un ecosistema enorme.

Moverse demasiado lentamente convertiría Django en un museo.

Por ahora, el proyecto sigue caminando bastante bien sobre esa línea.

Django no intenta ser el framework más pequeño. Intenta hacer desaparecer suficientes problemas corrientes para que puedas dedicar tu tiempo a los problemas particulares de tu aplicación.

Puntos de atención

Django 6.1 no es una LTS

A 8 de agosto de 2026, Django 6.1 es la versión oficial más reciente.

Su soporte principal debería terminar en abril de 2027.

Su soporte extendido, en diciembre de 2027.

La rama 5.2 LTS sigue soportada hasta abril de 2028.

Esto crea dos estrategias perfectamente legítimas.

Proyecto que quiere las funciones recientes:

Django 6.1

Proyecto que prioriza una ventana de soporte larga y muy estable:

Django 5.2 LTS

La próxima LTS prevista es Django 6.2, anunciada para abril de 2027.

Una versión más reciente no es, por tanto, automáticamente una mejor elección operativa.

Django 6.1 requiere un Python reciente

Django 6.1 soporta oficialmente:

Python 3.12;

3.13;

3.14.

Un proyecto antiguo que todavía utiliza Python 3.10 o 3.11 no puede simplemente instalar Django 6.1 y esperar que todo negocie amablemente.

Django 5.2 es la última serie que conserva soporte para Python 3.10 y 3.11.

Una actualización de Django puede implicar, por tanto, una actualización de Python.

Después una revisión de las dependencias.

Después tests.

Y después, quizá, una taza de café suficientemente grande.

El ORM no elimina la necesidad de comprender SQL

Escribir:

Article.objects.all()

es fácil.

Escribir una consulta ORM que provoque 4.000 consultas SQL sin darte cuenta, desgraciadamente, también.

El clásico problema de N+1 sigue siendo posible.

Django proporciona:

select_related()

prefetch_related()

y, desde Django 6.1, nuevos fetch modes capaces de mejorar determinados escenarios de lazy loading.

Pero ninguna abstracción elimina completamente la necesidad de comprender:

joins;

índices;

cardinalidad;

transacciones;

coste de las consultas.

Un ORM hace SQL más cómodo.

No intelectualmente opcional.

Las migraciones pueden entrar en conflicto

Dos desarrolladores modifican el mismo modelo en dos ramas.

Cada uno genera una migración.

Las ramas se fusionan.

Django descubre ahora dos futuros diferentes para la misma historia.

A veces hay que fusionar o reorganizar las migraciones.

No es una debilidad específica de Django.

Es la consecuencia lógica de querer versionar la evolución de una base de datos dentro de un proyecto distribuido.

Pero cuanto más desarrolladores y migraciones tiene una aplicación, más importante se vuelve esta disciplina.

El admin no es una interfaz de usuario universal

Django Admin está pensado para usuarios de confianza que gestionan datos.

Puede personalizarse.

Mucho.

Pero intentar transformarlo en un frontend para el gran público encuentra rápidamente límites.

UX.

Navegación.

Diseño.

Workflows muy específicos.

Mobile.

Interacciones avanzadas.

El admin es excelente cuando permanece cerca de su intención:

administrar los datos del sistema.

Para el producto final, suele ser preferible construir vistas dedicadas.

runserver no es un servidor de producción

El comando:

python manage.py runserver

es fantástico para desarrollar.

No está destinado a servir una aplicación en producción.

Django debe desplegarse entonces a través de una infraestructura adecuada utilizando WSGI o ASGI.

Por ejemplo:

Gunicorn;

uWSGI;

Uvicorn;

Daphne;

Hypercorn;

según la arquitectura elegida.

También hay que gestionar:

reverse proxy;

HTTPS;

procesos;

logs;

monitoring;

statics;

media;

timeouts;

reinicios;

seguridad.

El botón «deploy» no viene incluido en el framework.

DEBUG = True nunca debe terminar en producción

Durante el desarrollo, DEBUG = True proporciona páginas de error extremadamente detalladas.

Tracebacks.

Variables.

Settings.

Información sobre el código.

Es maravilloso mientras se desarrolla.

Y exactamente el tipo de información que no queremos mostrar a un desconocido en Internet.

En producción:

DEBUG = False

no es una sugerencia estética.

Es una medida básica de seguridad.

La SECRET_KEY es realmente secreta

Django utiliza SECRET_KEY para varios mecanismos criptográficos de firma.

No debe:

commitearse públicamente;

reutilizarse en todas partes;

hardcodearse en un repository público;

copiarse desde un tutorial.

En producción, debe proceder de una fuente segura:

variable de entorno;

gestor de secretos;

configuración privada.

Django incluso proporciona manage.py check --deploy para señalar varias configuraciones peligrosas.

El framework intenta avisar.

Pero no puede arrancarle el archivo .env de las manos al desarrollador antes del git add ..

Los archivos estáticos y media requieren una estrategia real

CSS.

JavaScript.

Imágenes de la interfaz.

Uploads de usuarios.

Estos elementos no deben tratarse exactamente igual que el código Python.

Django dispone de:

STATIC_URL

STATIC_ROOT

MEDIA_URL

MEDIA_ROOT

y del comando:

python manage.py collectstatic

Pero en producción hay que decidir dónde viven realmente esos archivos.

Nginx.

CDN.

S3 o almacenamiento compatible.

Volumen persistente.

Servicio externo.

Los uploads de usuarios son especialmente importantes.

El container de la aplicación puede ser desechable.

Las fotos de los usuarios, bastante menos.

El sistema de tareas todavía no proporciona toda la infraestructura

Django 6.0 añadió un framework de tareas.

Es una evolución importante.

Pero Django no proporciona un worker de producción integrado que ejecute esas tareas por sí solo.

Sigue siendo necesaria una infraestructura externa.

Por tanto, no hay que leer:

«Django ahora tiene tareas»

como:

«Celery, Redis y los workers ya no existen».

El nuevo framework estandariza una parte de la API.

La ejecución sigue dependiendo del backend y de la arquitectura elegidos.

Async no significa que todo Django se haya convertido en async

Django soporta WSGI y ASGI.

Tiene vistas async y un número creciente de APIs asíncronas.

Pero algunas partes del framework o del ecosistema siguen siendo síncronas.

Por tanto, un proyecto debe comprender dónde se encuentran las fronteras.

De lo contrario, se puede crear una vista:

async def mi_vista(request):
    ...

y llamar inmediatamente dentro a tres bibliotecas bloqueantes.

La palabra async está claramente presente.

El beneficio, un poco menos.

Django REST Framework no es Django

La confusión es frecuente.

Django REST Framework — DRF es un proyecto de terceros construido sobre Django.

Tiene su propia versión.

Su propia documentación.

Su propio ciclo de mantenimiento.

Django por sí mismo puede producir JSON y construir una API.

Pero los serializers, viewsets y muchas funciones REST asociadas habitualmente con Django proceden a menudo de DRF.

Esta diferencia importa cuando se evalúan las dependencias de un proyecto.

Un frontend moderno puede añadir una segunda arquitectura completa

Django + React.

Django + Vue.

Django + Next.js.

Es perfectamente válido.

Pero a veces significa:

routing backend;

routing frontend;

validación backend;

validación frontend;

auth backend;

estado frontend;

build Node;

build Python;

API;

CORS;

dos ecosistemas de dependencias.

Una SPA no es, por tanto, automáticamente «más moderna».

Es principalmente una arquitectura diferente.

Para algunas aplicaciones resulta indispensable.

Para otras, los templates Django acompañados de HTMX o de un poco de JavaScript pueden ser mucho más sencillos.

Las aplicaciones Django pueden convertirse en monolitos muy cómodos

Django facilita añadir funcionalidades.

A veces demasiado bien.

Se añade una app.

Después otra.

Después un modelo.

Después una lógica en signals.py.

Después una función en utils.py.

Después un servicio.

Después un método de modelo que envía un email y modifica otras tres tablas porque «era práctico».

Diez años más tarde, el monolito sigue funcionando.

Nadie se atreve a mirarlo directamente.

Django no crea este problema.

Pero su productividad puede permitir que un proyecto se vuelva grande antes de que el equipo se vea obligado a pensar seriamente en los límites arquitectónicos.

Los signals son potentes y fáciles de volver invisibles

Django posee un sistema de signals.

Se guarda un objeto.

Una función se ejecuta en otro lugar.

Es práctico para desacoplar determinadas operaciones.

Pero demasiados signals pueden transformar el flujo del programa en una búsqueda del tesoro.

Guardas un usuario.

¿Por qué se han enviado tres emails?

¿Por qué acaba de crearse una factura?

¿Por qué ha cambiado la cache?

Ah.

post_save.

En una aplicación de negocio importante, una lógica explícita suele ser más fácil de seguir que un bosque de efectos secundarios invisibles.

Elegir SQLite al principio puede ocultar determinados comportamientos

SQLite es perfecta para:

aprender;

hacer tests;

prototipar;

pequeños proyectos.

Está integrada en Python y requiere muy poca configuración.

Pero PostgreSQL, MySQL, MariaDB y Oracle no se comportan exactamente igual.

Tipos.

Restricciones.

Concurrencia.

Funciones SQL.

Transacciones.

Si una aplicación importante va a utilizar PostgreSQL en producción, desarrollar suficientemente pronto con PostgreSQL reduce el riesgo de descubrir esas diferencias la víspera del despliegue.

La documentación de Django recomienda además esta coherencia para proyectos importantes.

Una nueva versión de Django merece leer las release notes

Django posee un sistema de deprecación relativamente disciplinado.

Pero una actualización puede aun así introducir:

cambios incompatibles;

eliminaciones;

nuevas versiones mínimas de bases de datos;

evolución de dependencias;

nuevos comportamientos.

Django 6.1, por ejemplo, exige ahora como mínimo:

PostgreSQL 15;

MySQL 8.4;

MariaDB 10.11;

SQLite 3.37.

Actualizar el framework sin mirar la infraestructura que hay debajo puede, por tanto, producir algunas sorpresas.

Open source no significa «sin mantenimiento»

Django es gratuito.

BSD.

Open source.

Sin licencia comercial por usuario.

Sin suscripción para activar el ORM premium.

Pero una aplicación Django real sigue teniendo un coste.

Servidor.

Base de datos.

Almacenamiento.

Backups.

Emails.

CDN.

Monitoring.

Mantenimiento.

Actualizaciones de seguridad.

Desarrollo.

El framework es gratuito.

La aplicación que utiliza el framework sigue viviendo en el mundo físico de las facturas y las máquinas.

¿Cuándo es Django demasiado grande?

Si el proyecto consiste esencialmente en:

tres endpoints;

ninguna base de datos compleja;

ningún back-office;

ningún usuario;

ningún formulario;

ninguna sesión;

ninguna lógica de negocio significativa;

entonces Django puede parecer efectivamente pesado.

FastAPI o Flask pueden ser más directos.

A la inversa, si tres meses después el pequeño servicio posee:

usuarios;

permisos;

emails;

veinte modelos;

admin;

dashboard;

back-office;

pagos;

entonces la cantidad de funcionalidades de Django empieza de repente a parecerse menos a peso y más a trabajo que ya está hecho.

Probablemente sea la manera correcta de elegir.

No:

«¿Django es moderno?»

Sino:

«¿cuántos de los problemas que resuelve Django voy a encontrar realmente?»

Django merece especialmente la pena cuando tu aplicación tiene suficiente lógica de negocio, datos y usuarios como para que reconstruir las bases empiece a convertirse en una distracción.