Mira la lección en vídeo
Accede al vídeo completo de esta lección y a más contenido exclusivo con el Plan Plus.
Desbloquear Plan PlusCreación de Blueprints
Los Blueprints en Flask son una herramienta fundamental para organizar aplicaciones web de gran escala. Funcionan como contenedores que agrupan rutas, plantillas y funciones relacionadas, permitiendo dividir una aplicación monolítica en módulos independientes y reutilizables.
Un Blueprint actúa como un plano arquitectónico que define cómo debe estructurarse una parte específica de tu aplicación. A diferencia de crear todas las rutas directamente en el archivo principal, los Blueprints te permiten definir rutas en archivos separados y luego registrarlas en la aplicación principal cuando sea necesario.
Estructura básica de un Blueprint
Para crear un Blueprint, necesitas importar la clase Blueprint
desde Flask y definir una instancia con un nombre único y la ubicación del módulo:
from flask import Blueprint
# Crear una instancia de Blueprint
usuarios_bp = Blueprint('usuarios', __name__)
@usuarios_bp.route('/perfil')
def mostrar_perfil():
return '<h1>Perfil de usuario</h1>'
@usuarios_bp.route('/configuracion')
def configuracion():
return '<h1>Configuración de usuario</h1>'
El primer parámetro ('usuarios'
) es el nombre del Blueprint, que debe ser único en toda la aplicación. El segundo parámetro (__name__
) indica el módulo donde se define el Blueprint, permitiendo a Flask localizar recursos como plantillas y archivos estáticos.
Creación de un Blueprint completo
Vamos a crear un Blueprint más completo para gestionar productos en una tienda online. Primero, creamos un archivo separado llamado productos.py
:
from flask import Blueprint, render_template, request, redirect, url_for
# Definir el Blueprint
productos_bp = Blueprint('productos', __name__, url_prefix='/productos')
# Lista temporal de productos (en una aplicación real usarías una base de datos)
productos_lista = [
{'id': 1, 'nombre': 'Laptop', 'precio': 899.99},
{'id': 2, 'nombre': 'Mouse', 'precio': 25.50},
{'id': 3, 'nombre': 'Teclado', 'precio': 75.00}
]
@productos_bp.route('/')
def listar_productos():
return render_template('productos/lista.html', productos=productos_lista)
@productos_bp.route('/<int:producto_id>')
def detalle_producto(producto_id):
producto = next((p for p in productos_lista if p['id'] == producto_id), None)
if producto:
return render_template('productos/detalle.html', producto=producto)
return '<h1>Producto no encontrado</h1>', 404
@productos_bp.route('/nuevo', methods=['GET', 'POST'])
def crear_producto():
if request.method == 'POST':
nuevo_producto = {
'id': len(productos_lista) + 1,
'nombre': request.form['nombre'],
'precio': float(request.form['precio'])
}
productos_lista.append(nuevo_producto)
return redirect(url_for('productos.listar_productos'))
return render_template('productos/formulario.html')
En este ejemplo, hemos añadido el parámetro url_prefix='/productos'
al crear el Blueprint. Esto significa que todas las rutas definidas en este Blueprint tendrán automáticamente el prefijo /productos
en su URL final.
Blueprints con plantillas específicas
Los Blueprints pueden tener sus propias carpetas de plantillas y archivos estáticos. Para organizar mejor el proyecto, puedes crear una estructura de directorios específica:
mi_aplicacion/
├── app.py
├── productos.py
└── templates/
└── productos/
├── lista.html
├── detalle.html
└── formulario.html
Si quieres que el Blueprint tenga su propia carpeta de plantillas independiente, puedes especificarla al crear el Blueprint:
from flask import Blueprint
productos_bp = Blueprint(
'productos',
__name__,
url_prefix='/productos',
template_folder='templates/productos',
static_folder='static/productos'
)
Funciones auxiliares en Blueprints
Los Blueprints también pueden incluir funciones auxiliares y decoradores personalizados que solo se aplican a las rutas de ese módulo:
from flask import Blueprint, session, redirect, url_for
from functools import wraps
admin_bp = Blueprint('admin', __name__, url_prefix='/admin')
def requiere_admin(f):
@wraps(f)
def funcion_decorada(*args, **kwargs):
if not session.get('es_admin'):
return redirect(url_for('auth.login'))
return f(*args, **kwargs)
return funcion_decorada
@admin_bp.route('/dashboard')
@requiere_admin
def dashboard():
return '<h1>Panel de administración</h1>'
@admin_bp.route('/usuarios')
@requiere_admin
def gestionar_usuarios():
return '<h1>Gestión de usuarios</h1>'
@admin_bp.before_request
def verificar_permisos():
# Esta función se ejecuta antes de cada petición al Blueprint
if not session.get('usuario_logueado'):
return redirect(url_for('auth.login'))
El decorador @admin_bp.before_request
se ejecuta antes de procesar cualquier ruta dentro del Blueprint, permitiendo implementar lógica común como verificaciones de autenticación o logging específico del módulo.
Manejo de errores específicos del Blueprint
Cada Blueprint puede definir sus propios manejadores de errores que solo se aplican a las rutas de ese módulo:
from flask import Blueprint, render_template
tienda_bp = Blueprint('tienda', __name__)
@tienda_bp.errorhandler(404)
def producto_no_encontrado(error):
return render_template('tienda/error_404.html'), 404
@tienda_bp.errorhandler(500)
def error_interno_tienda(error):
return render_template('tienda/error_500.html'), 500
@tienda_bp.route('/producto/<int:id>')
def mostrar_producto(id):
# Si el producto no existe, se activará el manejador 404 del Blueprint
if id > 1000:
abort(404)
return f'<h1>Producto {id}</h1>'
Esta aproximación permite que cada módulo de tu aplicación tenga un comportamiento específico ante errores, manteniendo la coherencia visual y funcional dentro de cada sección.
Registro y organización
Guarda tu progreso
Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.
Más de 25.000 desarrolladores ya confían en CertiDevs
Una vez creados los Blueprints, el siguiente paso es registrarlos en la aplicación principal y establecer una estructura organizativa que facilite el mantenimiento del código. El registro conecta los módulos independientes con la aplicación Flask, mientras que una buena organización permite escalar el proyecto sin perder claridad.
Registro de Blueprints en la aplicación principal
Para que Flask reconozca y utilice un Blueprint, debes registrarlo en la aplicación principal usando el método register_blueprint()
. Este proceso se realiza típicamente en el archivo principal de la aplicación:
from flask import Flask
from productos import productos_bp
from usuarios import usuarios_bp
from admin import admin_bp
app = Flask(__name__)
app.secret_key = 'tu_clave_secreta_aqui'
# Registrar los Blueprints
app.register_blueprint(productos_bp)
app.register_blueprint(usuarios_bp)
app.register_blueprint(admin_bp)
@app.route('/')
def inicio():
return '<h1>Página principal</h1>'
if __name__ == '__main__':
app.run(debug=True)
El orden de registro puede ser importante si tienes rutas que podrían entrar en conflicto. Flask procesa las rutas en el orden en que se registran los Blueprints, por lo que el primer Blueprint registrado tendrá prioridad sobre rutas similares.
Configuración avanzada durante el registro
El método register_blueprint()
acepta varios parámetros que permiten personalizar el comportamiento del Blueprint al momento del registro:
from flask import Flask
from productos import productos_bp
from api import api_bp
app = Flask(__name__)
# Registro básico
app.register_blueprint(productos_bp)
# Registro con prefijo personalizado (sobrescribe el del Blueprint)
app.register_blueprint(api_bp, url_prefix='/api/v2')
# Registro con subdominio específico
app.register_blueprint(admin_bp, subdomain='admin')
# Registro condicional basado en configuración
if app.config.get('HABILITAR_PANEL_ADMIN'):
app.register_blueprint(admin_bp, url_prefix='/panel')
Esta flexibilidad permite adaptar los Blueprints a diferentes entornos o configuraciones sin modificar el código del Blueprint original.
Estructura de directorios recomendada
Una organización clara del proyecto facilita la colaboración y el mantenimiento. Aquí tienes una estructura recomendada para proyectos Flask con múltiples Blueprints:
mi_proyecto_flask/
├── app.py # Aplicación principal
├── config.py # Configuraciones
├── requirements.txt # Dependencias
├── blueprints/ # Carpeta de Blueprints
│ ├── __init__.py
│ ├── productos/
│ │ ├── __init__.py
│ │ ├── routes.py # Rutas del Blueprint
│ │ ├── forms.py # Formularios WTForms
│ │ └── utils.py # Funciones auxiliares
│ ├── usuarios/
│ │ ├── __init__.py
│ │ ├── routes.py
│ │ └── models.py # Modelos específicos
│ └── admin/
│ ├── __init__.py
│ └── routes.py
├── templates/
│ ├── base.html
│ ├── productos/
│ │ ├── lista.html
│ │ └── detalle.html
│ └── usuarios/
│ └── perfil.html
└── static/
├── css/
├── js/
└── img/
Implementación de Blueprints modulares
Para proyectos más grandes, puedes crear Blueprints modulares donde cada Blueprint se define en su propio paquete. Aquí tienes un ejemplo de cómo estructurar el Blueprint de productos:
blueprints/productos/init.py:
from flask import Blueprint
productos_bp = Blueprint(
'productos',
__name__,
url_prefix='/productos',
template_folder='../../templates/productos'
)
from . import routes
blueprints/productos/routes.py:
from flask import render_template, request, redirect, url_for
from . import productos_bp
@productos_bp.route('/')
def listar():
return render_template('productos/lista.html')
@productos_bp.route('/crear', methods=['GET', 'POST'])
def crear():
if request.method == 'POST':
# Lógica para crear producto
return redirect(url_for('productos.listar'))
return render_template('productos/crear.html')
app.py actualizado:
from flask import Flask
from blueprints.productos import productos_bp
from blueprints.usuarios import usuarios_bp
def crear_app():
app = Flask(__name__)
app.config.from_object('config.Config')
# Registrar Blueprints
app.register_blueprint(productos_bp)
app.register_blueprint(usuarios_bp)
return app
if __name__ == '__main__':
app = crear_app()
app.run(debug=True)
Organización por funcionalidad vs por tipo
Existen dos enfoques principales para organizar Blueprints en proyectos grandes:
Organización por funcionalidad (recomendada):
blueprints/
├── tienda/ # Todo relacionado con la tienda
│ ├── routes.py
│ ├── models.py
│ └── forms.py
├── blog/ # Todo relacionado con el blog
│ ├── routes.py
│ ├── models.py
│ └── utils.py
└── auth/ # Todo relacionado con autenticación
├── routes.py
└── decorators.py
Organización por tipo de archivo:
blueprints/
├── routes/
│ ├── tienda.py
│ ├── blog.py
│ └── auth.py
├── models/
│ ├── producto.py
│ └── usuario.py
└── forms/
├── tienda_forms.py
└── auth_forms.py
La organización por funcionalidad es generalmente preferible porque mantiene relacionados todos los archivos que trabajan juntos, facilitando el desarrollo y mantenimiento de cada módulo.
Gestión de dependencias entre Blueprints
Cuando los Blueprints necesitan interactuar entre sí, es importante evitar importaciones circulares y mantener un acoplamiento bajo:
# blueprints/productos/routes.py
from flask import url_for, redirect
from . import productos_bp
@productos_bp.route('/comprar/<int:producto_id>')
def comprar_producto(producto_id):
# En lugar de importar directamente el Blueprint de usuarios
# Usa url_for con el nombre del Blueprint
return redirect(url_for('usuarios.login'))
# blueprints/usuarios/routes.py
from . import usuarios_bp
@usuarios_bp.route('/mis-compras')
def mis_compras():
# Redirigir a productos usando url_for
return redirect(url_for('productos.listar'))
Esta aproximación mantiene los Blueprints independientes mientras permite la navegación fluida entre diferentes secciones de la aplicación.
Configuración específica por Blueprint
Algunos Blueprints pueden requerir configuraciones específicas que solo se aplican a ese módulo. Puedes manejar esto durante el registro:
from flask import Flask
def crear_app(config_name='development'):
app = Flask(__name__)
# Configuración general
app.config.from_object(f'config.{config_name.title()}Config')
# Registrar Blueprint con configuración específica
from blueprints.api import api_bp
app.register_blueprint(api_bp)
# Configurar límites específicos para el Blueprint API
if hasattr(app.config, 'API_RATE_LIMIT'):
# Aplicar configuración específica del Blueprint
pass
return app
Esta estructura permite que cada Blueprint tenga sus propias configuraciones sin afectar el resto de la aplicación, manteniendo la modularidad y flexibilidad del sistema.
Aprendizajes de esta lección de Flask
- Comprender qué son los Blueprints y su utilidad para organizar aplicaciones Flask.
- Aprender a crear Blueprints con rutas, plantillas y funciones auxiliares.
- Saber cómo registrar Blueprints en la aplicación principal y configurar sus parámetros.
- Conocer las mejores prácticas para estructurar proyectos con múltiples Blueprints.
- Entender cómo manejar dependencias, errores y configuraciones específicas por Blueprint.
Completa este curso de Flask y certifícate
Únete a nuestra plataforma de cursos de programación y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.
Asistente IA
Resuelve dudas al instante
Ejercicios
Practica con proyectos reales
Certificados
Valida tus conocimientos
Más de 25.000 desarrolladores ya se han certificado con CertiDevs