es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Django import-export, solo exportar un objeto con objetos relacionados.

Tengo un formulario que permite a un usuario registrarse en nuestro sitio web. Ahora necesito exportar todos los datos a Excel, así que recurrí al paquete de importación-exportación. Tengo 3 modelos, Cliente, Referencia y Contacto. Los dos últimos tienen una relación m2m con Cliente. También creé Recursos para estos modelos. Cuando uso Resource().export() al final de mi método done() en mi vista de formulario, exporta todos los objetos existentes en la base de datos, lo cual no es lo que quiero.

Intenté buscar esto en Google y solo obtuve un resultado, que básicamente dice que necesito usar before_export(), pero no puedo encontrar en ninguna parte de la documentación cómo funciona en realidad.

Intenté consultar manualmente a mi cliente de esta manera:

cliente = Cliente.objects.filter(pk=cliente.id)

datos_cliente = RecursoCliente().export(cliente)

Lo cual funciona bien, pero luego estoy atascado con las referencias y los contactos relacionados: datos_referencia = RecursoReferencia().export(cliente.referencias) me da un TypeError que dice que el objeto ManyRelatedManager no es iterable. Lo cual tiene sentido porque export() espera una queryset, pero no estoy seguro de si es posible obtenerlo de esa manera.

¡Agradezco cualquier ayuda!

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Solución para exportar datos específicos utilizando django-import-export en Django

    Cuando se utiliza django-import-export para exportar datos a Excel, a veces solo queremos exportar datos específicos en lugar de todos los objetos existentes en la base de datos.

    En este escenario, el usuario tiene tres modelos: Customer (Cliente), Reference (Referencia) y Contact (Contacto). Tanto Reference como Contact tienen una relación de muchos a muchos con Customer, y el usuario ha creado recursos para estos modelos.

    Para exportar datos específicos, el usuario puede utilizar before_export() en su clase de recurso. Este método se llama justo antes de la exportación y le permite al usuario modificar los datos a exportar.

    Por ejemplo, el usuario puede anular before_export() para filtrar los datos que desea exportar según alguna condición. En este caso, el usuario puede filtrar el objeto Customer y sus objetos relacionados Reference y Contact, de la siguiente manera:

    class CustomerResource(resources.ModelResource):
        references = fields.Field()
        contacts = fields.Field()
    
        class Meta:
            model = Customer
            fields = ('id', 'name', 'email')
    
        def dehydrate_references(self, customer):
            references = customer.references.all()
            return "\n".join([reference.name for reference in references])
    
        def dehydrate_contacts(self, customer):
            contacts = customer.contacts.all()
            return "\n".join([contact.name for contact in contacts])
    
        def before_export(self, queryset, *args, **kwargs):
            queryset = super().before_export(queryset, *args, **kwargs)
    
            customer_ids = [obj.pk for obj in queryset]
            customers = Customer.objects.filter(pk__in=customer_ids)
            for customer in customers:
                customer.references = customer.references.all()
                customer.contacts = customer.contacts.all()
    
            return customers
    

    En before_export(), el usuario primero obtiene los pk de todos los objetos Customer en queryset. Luego filtra los objetos Customer en función de los pk y, para cada Customer, asigna sus objetos relacionados Reference y Contact.

    Tenga en cuenta que los campos references y contacts deben estar definidos en la clase de recurso, y también se deben definir dehydrate_references() y dehydrate_contacts() para exportar correctamente los objetos relacionados.

    Ahora, al llamar a Resource().export() en la vista, solo se exportarán los datos filtrados a Excel.

Comments are closed.