Sistema flexible de importación de datos para Django con soporte para XLSX, CSV y JSON
Project description
Django FlexImporter
Sistema flexible de importación de datos para Django que permite crear importadores personalizados mediante herencia de clases, con soporte para múltiples formatos (XLSX, CSV, JSON) y validación automática de datos.
📚 Documentación
- Guía Rápida (QUICKSTART.md): Crea un importador en menos de 10 líneas
- Demo Completa (DEMO.md): Walkthrough paso a paso con ejemplos
- Guía de key_field (KEY_FIELD_GUIDE.md): Actualización automática de registros existentes
- Configuración de Celery (CELERY_SETUP.md): Importaciones asíncronas para miles de registros
- Solución de Problemas (TROUBLESHOOTING.md): Problemas comunes y soluciones
- Este README: Documentación completa de referencia
Características
- Importadores Personalizables: Define tus propios importadores heredando de
FlexImporteroFlexModelImporter - Importadores desde Modelos: Crea importadores automáticamente desde modelos Django
- Actualización Inteligente: Usa
key_fieldpara actualizar registros existentes en lugar de crear duplicados - Procesamiento Asíncrono: Soporte opcional para Celery para importaciones de miles de registros
- Múltiples Formatos: Soporte para XLSX, CSV y JSON
- Validación Automática: Validación de tipos de datos y campos requeridos
- Generación de Plantillas: Descarga plantillas en cualquier formato soportado
- Bitácora Completa: Registro detallado de todas las importaciones con estadísticas de creados/actualizados
- Re-ejecución: Capacidad de re-ejecutar importaciones anteriores
- Interfaz Admin: Integración completa con Django Admin
- Seguimiento en Tiempo Real: Log de progreso y estadísticas de importación con auto-refresh
Instalación
Instalación desde PyPI (Recomendado)
pip install django-flex-importer
Para soporte asíncrono con Celery:
pip install django-flex-importer[async]
Configuración
- Agrega
flex_importeraINSTALLED_APPSensettings.py:
INSTALLED_APPS = [
# ...
'flex_importer',
# ...
]
- Ejecuta las migraciones:
python manage.py migrate flex_importer
- (Opcional) Configurar Celery para procesamiento asíncrono:
# settings.py
CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
Ver CELERY_SETUP.md para más detalles.
Instalación desde el código fuente
Si quieres contribuir o usar la última versión de desarrollo:
# 1. Clonar el repositorio
git clone https://github.com/twine003/django-flex-importer.git
cd django-flex-importer
# 2. Crear entorno virtual
python -m venv venv
source venv/bin/activate # En Windows: venv\Scripts\activate
# 3. Instalar en modo desarrollo
pip install -e ".[dev]"
# 4. Ejecutar migraciones
python manage.py migrate
# 5. Crear superusuario
python manage.py createsuperuser
# 6. Ejecutar servidor
python manage.py runserver
Uso
Hay dos formas de crear importadores:
1. FlexModelImporter (Recomendado - Automático desde Modelo)
La forma más rápida es usar FlexModelImporter que automáticamente extrae los campos del modelo:
from flex_importer.model_importer import FlexModelImporter
from .models import Sale
class SalesModelImporter(FlexModelImporter):
"""Importador automático desde el modelo Sale"""
class Meta:
model = Sale # El modelo del cual extraer los campos
verbose_name = "Importador de Ventas (desde Modelo)"
can_re_run = True
# Opcional: excluir campos específicos
# exclude_fields = ['some_field']
# Opcional: incluir solo campos específicos
# include_fields = ['date', 'cliente', 'producto', 'cantidad', 'precio']
def import_action(self, row_data):
"""
Implementa la lógica de importación.
Args:
row_data (dict): Datos validados de la fila
Returns:
bool or str: True si es exitoso, mensaje de error si falla
"""
try:
# Valores por defecto para campos opcionales
if row_data.get('cantidad') is None:
row_data['cantidad'] = 1
# Usar el helper para crear la instancia
sale = self.create_instance(row_data)
return True
except Exception as e:
return f"Error: {str(e)}"
Ventajas de FlexModelImporter:
- ✅ No necesitas definir los campos manualmente
- ✅ Automáticamente sincronizado con el modelo
- ✅ Menos código y más mantenible
- ✅ Incluye métodos helper:
create_instance()yupdate_or_create_instance()
2. FlexImporter (Manual - Mayor Control)
Si necesitas mayor control sobre los campos, usa FlexImporter:
Crea un archivo importers.py en tu app de Django y define tu importador:
from django.db import models
from flex_importer.base import FlexImporter
from .models import Sale
class SalesImporter(FlexImporter):
"""Importador de ventas"""
# Define los campos usando tipos de Django
date = models.DateTimeField(verbose_name='Fecha de Venta')
cliente = models.TextField(verbose_name='Nombre del Cliente')
producto = models.IntegerField(verbose_name='ID del Producto')
cantidad = models.IntegerField(verbose_name='Cantidad', blank=True)
precio = models.DecimalField(
verbose_name='Precio Unitario',
max_digits=10,
decimal_places=2
)
class Meta:
verbose_name = "Importador de Ventas"
can_re_run = True # Permite re-ejecutar importaciones
def import_action(self, row_data):
"""
Implementa la lógica de importación.
Args:
row_data (dict): Datos validados de la fila
Returns:
bool or str: True si es exitoso, mensaje de error si falla
"""
try:
# Valor por defecto para campos opcionales
if row_data.get('cantidad') is None:
row_data['cantidad'] = 1
# Crear el objeto
sale = Sale.objects.create(
date=row_data['date'],
cliente=row_data['cliente'],
producto=row_data['producto'],
cantidad=row_data['cantidad'],
precio=row_data['precio']
)
return True
except Exception as e:
return f"Error al crear venta: {str(e)}"
3. Métodos Helper de FlexModelImporter
FlexModelImporter incluye métodos útiles para facilitar la importación:
create_instance(validated_data)
Crea una nueva instancia del modelo:
def import_action(self, row_data):
sale = self.create_instance(row_data)
return True
update_or_create_instance(lookup_fields, validated_data)
Actualiza o crea una instancia basándose en campos de búsqueda:
def import_action(self, row_data):
# Buscar por 'producto' y actualizar o crear
lookup = {'producto': row_data.pop('producto')}
sale, created = self.update_or_create_instance(lookup, row_data)
if created:
return True
else:
return "Registro actualizado"
4. Tipos de Campos Soportados
El sistema soporta los siguientes tipos de campos de Django:
CharField/TextField: TextoIntegerField: Números enterosFloatField: Números decimalesDecimalField: Decimales precisosBooleanField: Booleanos (true/false, yes/no, si/no, 1/0)DateField: Fechas (formato: YYYY-MM-DD)DateTimeField: Fechas con hora (formato ISO)EmailField: Correos electrónicosForeignKey: Acepta el ID del objeto relacionado
5. Configuración Meta
La clase Meta del importador soporta las siguientes opciones:
Para FlexImporter y FlexModelImporter:
verbose_name: Nombre que aparecerá en el selector del admincan_re_run: SiTrue, permite re-ejecutar importaciones anteriores
Adicionales para FlexModelImporter:
model: El modelo Django del cual extraer los campos (requerido)exclude_fields: Lista de campos a excluir (opcional)include_fields: Lista de campos a incluir (si se especifica, solo se incluyen estos campos)
6. Usar el Importador
Desde el Django Admin:
- Ve a "Bitácoras de Importación" en el admin
- Haz clic en "Nueva Importación"
- Selecciona tu importador del dropdown
- Descarga la plantilla en el formato deseado (XLSX, CSV o JSON)
- Llena la plantilla con tus datos
- Selecciona el formato del archivo
- Sube el archivo completado
- Haz clic en "Importar"
Estructura de las Plantillas:
XLSX/CSV:
- La primera fila contiene los encabezados (nombres de los campos)
- Los campos requeridos se marcan con asterisco (*)
- Las filas siguientes contienen los datos
JSON:
{
"template_info": {
"importer": "Importador de Ventas",
"fields": [
{
"name": "date",
"verbose_name": "Fecha de Venta",
"type": "datetime",
"required": true
},
...
]
},
"data": [
{
"date": "2024-01-15T10:30:00",
"cliente": "Juan Pérez",
"producto": 101,
"cantidad": 5,
"precio": "29.99"
}
]
}
7. Bitácora de Importaciones
Cada importación se registra con:
- Estado: Pendiente, Procesando, Exitoso, Parcial, Fallido
- Estadísticas: Total de filas, procesadas, exitosas, con error
- Tasa de Éxito: Porcentaje de filas importadas correctamente
- Detalles de Errores: Información específica sobre cada error
- Log de Progreso: Registro cronológico de la importación
- Archivo Original: El archivo importado se guarda para referencia
- Duración: Tiempo que tomó la importación
8. Re-ejecutar Importaciones
Si un importador tiene can_re_run = True:
- Ve al detalle de una importación en el admin
- Haz clic en el botón "Re-ejecutar"
- Se creará una nueva importación usando el mismo archivo
Procesamiento Asíncrono con Celery
Para importaciones con miles de registros, el sistema soporta procesamiento asíncrono usando Celery.
¿Cuándo usar Celery?
- Sin Celery (síncrono): Funciona bien para cientos de registros
- Con Celery (asíncrono): Recomendado para miles de registros
Características del modo asíncrono:
- ✅ Detección automática: El sistema detecta si Celery está disponible
- ✅ Respuesta inmediata: No hay que esperar a que termine la importación
- ✅ Auto-refresh: La página de detalle se actualiza automáticamente cada 5 segundos
- ✅ Monitoreo en tiempo real: Ve el progreso mientras se procesa
- ✅ Sin cambios en el código: Tus importadores funcionan igual con o sin Celery
Configuración rápida:
# 1. Instalar Celery y Redis
pip install celery redis
# 2. Iniciar Redis
redis-server
# 3. Configurar en settings.py
CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
# 4. Iniciar worker de Celery
celery -A config worker --loglevel=info
Para más detalles: Ver CELERY_SETUP.md
Estructura del Proyecto
django-importer/
├── config/ # Configuración de Django
│ ├── settings.py
│ ├── celery.py # Configuración de Celery (opcional)
│ ├── urls.py
│ ├── wsgi.py
│ └── asgi.py
├── flex_importer/ # App principal de importación
│ ├── base.py # Clase base FlexImporter
│ ├── model_importer.py # Clase FlexModelImporter
│ ├── models.py # Modelo ImportLog
│ ├── admin.py # Admin personalizado
│ ├── processor.py # Procesador de importaciones
│ ├── tasks.py # Tareas de Celery (async)
│ ├── utils.py # Utilidades (detección de Celery)
│ ├── registry.py # Registro de importadores
│ └── templates/ # Templates del admin
├── example_app/ # App de ejemplo
│ ├── models.py # Modelo Sale
│ ├── admin.py # Admin de Sale
│ └── importers.py # Importadores de ejemplo
├── media/ # Archivos subidos
├── manage.py
└── requirements.txt
Validación de Datos
El sistema valida automáticamente:
- Campos Requeridos: Verifica que los campos obligatorios estén presentes
- Tipos de Datos: Convierte y valida los tipos de datos
- Formato: Valida formatos específicos (fechas, emails, etc.)
Los errores de validación se registran en la bitácora con:
- Número de fila
- Campo con error
- Mensaje de error detallado
- Datos de la fila
Ejemplo Completo
Ver example_app/importers.py para ejemplos completos de importadores.
El proyecto incluye tres importadores de ejemplo:
- SalesImporter: Importa ventas usando FlexImporter (definición manual de campos)
- SalesModelImporter: Importa ventas usando FlexModelImporter (automático desde modelo)
- ProductImporter: Importa productos y no puede ser re-ejecutado
Tecnologías
- Django 3.2+
- Python 3.7+
- openpyxl (para archivos Excel)
- SQLite (puede cambiarse a PostgreSQL, MySQL, etc.)
Licencia
MIT
Autor
Desarrollado para demostrar un sistema flexible de importación en Django.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_flex_importer-1.0.0.tar.gz.
File metadata
- Download URL: django_flex_importer-1.0.0.tar.gz
- Upload date:
- Size: 48.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ddf805fa485513c1d96f242121665d24cbb58707b41a2450e2c218666c9dfe6
|
|
| MD5 |
118032acc55bae6a74c81180511acdac
|
|
| BLAKE2b-256 |
42fe1992f10401739c7e563bc0bcbd9b5a62976f1cbc6cd1f0fef7024c3da44f
|
File details
Details for the file django_flex_importer-1.0.0-py3-none-any.whl.
File metadata
- Download URL: django_flex_importer-1.0.0-py3-none-any.whl
- Upload date:
- Size: 30.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6d4d78ca191ba6f01a7b89c6d7fb88069b7f3665a6daac5b8140cce0dd51d841
|
|
| MD5 |
70804cc05121d359373551d3b35d5b07
|
|
| BLAKE2b-256 |
dcc5f2d1f9d3a2510c79275278532e25ea47c95c37b0965c42b1a0b5d352007e
|