En esta ocasión veremos cómo importar datos desde un archivo en excel. Usaremos la librería django-import-export y como su nombre lo indica, es una librería para manejar la importación/exportación de datos.
Esta librería soporta muchos formatos, incluídos xls,csv, json, yaml y otros formatos soportados por tablib. También tiene una integración con el admin de django.
Para tal caso, tomaremos el código fuente del curso de Desarrollo Web con Python usando Django, pero crearemos una nueva aplicación.
manage.py startapp export
Y de acá, asumimos que ya has agregado en el Settings.py. Si tienes dudas, puedes ver en curso anteriomente mostrado haciendo click en este enlace.
Instalar Librería
pip install django-import-export
Y actualizamos el archivo de configuración agregándole la nueva librería
'import_export',
Adicionalmente, debemos agregar una configuración que permita que la importación se haga usando transacciones de la base de datos.
IMPORT_EXPORT_USE_TRANSACTIONS = True
Recursos
La librería django-import-export trabaja con el concepto de Recurso, el cual es definición de clases muy similiar a como Django maneja los modelos de formularios y las clases admin.Crearemos un modelo, el cual será donde se suba toda la información importada del archivo excel.
#models.py
from django.db import models
class Persona(models.Model):
nombre = models.CharField(max_length=30)
email = models.EmailField(blank=True)
fecha_nac = models.DateField()
ciudad = models.CharField(max_length=100, blank=True)
Se creará un archivo resource.py donde estará toda la lógica de la librería.
#resources.py
from import_export import resources
from .models import Persona
class PersonaResource(resources.ModelResource):
class Meta:
model = Persona
Esta es la definición más sencilla. Puedes pasarle diferentes configuraciones a la clase Meta,
como fields, exclude, etc. Puedes ver la documentación para más detalles
Importando Datos
Tomemos como ejemplo, el archivo xls siguiente
El Id debe estar presente porque es su llave primaria. Como será generado, no es necesario que se especifique.
Ahora crearemos la plantilla, le pondremos por nombre export/importar.html.
{% extends 'base/base.html' %}
{% block contenido %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="xlsfile">
<button type="submit">Subir</button>
</form>
{% endblock %}
Vista
from tablib import Dataset
def importar(request):
#template = loader.get_template('export/importar.html')
if request.method == 'POST':
persona_resource = PersonaResource()
dataset = Dataset()
#print(dataset)
nuevas_personas = request.FILES['xlsfile']
#print(nuevas_personas)
imported_data = dataset.load(nuevas_personas.read())
#print(dataset)
result = persona_resource.import_data(dataset, dry_run=True) # Test the data import
#print(result.has_errors())
if not result.has_errors():
persona_resource.import_data(dataset, dry_run=False) # Actually import now
return render(request, 'export/importar.html')
He dejado comentado algunos prints, que te serían muy interesante ver qué va pasando por ahí.
Probando
Debemos hacer las migraciones necesarias para que se cree el modelo en la base de datos y aplicarla. Luego de eso, debemos levantar el servidor. Y accedemos, sabemos que todo va bien si el log está "limpio" y la aplicación se carga en el login.
Creé una ruta (en el archivo urls.py de la app), /export/import
from django.urls import path
from .views import importar
urlpatterns = [
path('import', importar , name='import'),
]
Luego de las credenciales (que no sería necesario especificarla), accedo a la ruta http://127.0.0.1:8000/export/import.
Ahí cargo el archivo excel.
Y al presionar el botón subir, todo sucederá bastante rápido, ahí voy a revisar la tabla y esto es lo que encuentro.
Sólo teniendo cuidado que las fechas no las formatee Excel, en mi caso yo les antepuse una comilla simple para que siguiera en formato de texto.
Si te ha sido de utilidad este tutorial, te pediría lo compartas con tus amigos, conocidos y farmiliares.
Si estás interesado en aprender más, puedes inscribirte en el curso de Desarrollo Web con Python usando Django o ver alguno de los cursos para crecer como experto en desarrollo web con django viendo el siguiente enlace.
Bueno, será para la próxima.
¿Cuando se está actualizando los registros de un modelo el cual ya tiene información previa, el archivo de excel solo debe tener los registros a actualizar?
ResponderBorrar¿como importas el objetoResource desde la vista?
ResponderBorrarNo se si ya lo solucionaste o encontraste otra solucion, pero yo lo hice asi : from nombre.resources import ArticulosResource
BorrarSaludos
Estoy tratando de importar un reporte de SAP a una base de datos Postgres, voy a probar tu método, la única restricción que tiene mi app es que necesito por temas de seguimiento que se agregue la fecha de creación de cada registro de tal manera que un conjunto de datos de un solo archivo tengan la misma fecha ya que la tabla irá creciendo gradualmente.
ResponderBorrarfue más fácil utilizando la integración de django-import-export desde admin. Ya que en tiempo de ejecución al subir el xlsx retorna None cuando se carga info. No funciona tu método!
Borrar