Home > Software engineering >  django - StreamingHttpResponse export csv with fields name
django - StreamingHttpResponse export csv with fields name

Time:06-18

I have created a view to export from the database to a csv file, the code works fine, but the exported csv file does not have the field names, how can I add them?

i am using values_list because the performance is higher

I am using this code:

CSVStream.py:

class CSVBuffer:
    """An object that implements just the write method of the file-like
    interface.
    """
    def write(self, value):
        """Return the string to write."""
        return value

class CSVStream:
    """Class to stream (download) an iterator to a 
    CSV file."""
    def export(self, filename, iterator):
        # 1. Create our writer object with the pseudo buffer
        writer = csv.writer(CSVBuffer())

        # 2. Create the StreamingHttpResponse using our iterator as streaming content
        response = StreamingHttpResponse((writer.writerow(data) for data in iterator),
                                         content_type="text/csv")

        # 3. Add additional headers to the response
        response['Content-Disposition'] = f"attachment; filename={filename}.csv"
        # 4. Return the response
        return response

views.py

class descargarAsignacion(View):
    template_name='gestionAsignacion/detalle_Asignacion.html'
    
    def get(self, request,pk):
         # 1. Get the iterator of the QuerySet
               
        queryset=AsignacionSurtigas.objects.filter(idasignacion=pk)
       
        queryset_valueslist=queryset.values_list(
                "id",
                "idasignacion",
                "producto",
                "contrato",
                "nombre_suscriptor",
                "tipo_servicio",
                "total_deuda",
                "corriente_no_vencida_actual",
                "corrente_vencida",
                "total_deuda_corriente",
                "cuota_minima_agente",
                "politica_surtigas",
                "categoria",
                "estrato",
                "ref_anio",
                "historico_ref",
                "ciclo",
                "medidor",
                "lectura",
                "plan_acuerdo",
                "descripcion_barrio",
                "direccion",
                "dias_deuda",
                 named=True,
        )
        
        # 2. Create the instance of our CSVStream class
        csv_stream = CSVStream()

        # 3. Stream (download) the file
        return csv_stream.export("myfile", queryset_valueslist)

CodePudding user response:

You can add the header as the first element of the iterator that will be passed to csv_stream.export. One way of doing this is using itertools.chain

from itertools import chain

class descargarAsignacion(View):
    template_name='gestionAsignacion/detalle_Asignacion.html'

    def get(self, request,pk):

        # create the list in a separate variable. 
        #It's a list of tuple to be the same type of the returned queryset data
        values_list = [(
            "id",
            "idasignacion",
            "producto",
            "contrato",
        )]
           
        queryset=AsignacionSurtigas.objects.filter(idasignacion=pk)
   
        queryset_valueslist=queryset.values_list(
            *values_list    
            named=True,
        )
    
        csv_stream = CSVStream()

        # add values_list as the 1st item in the iterable
        return csv_stream.export("myfile", chain(values_list, queryset_valueslist))
  • Related