Este documento explica cómo generar CSV (valores separados por comas) dinámicamente usando vistas de Django. Para hacer esto, puede usar la biblioteca Python CSV o el sistema de plantillas Django.

Usar la biblioteca CSV de Python

Python viene con una biblioteca CSV, csv. los key usarlo con Django es que el csv La capacidad de creación de CSV del módulo actúa sobre objetos similares a archivos, y la capacidad de Django HttpResponse los objetos son objetos similares a archivos.

He aquí un ejemplo:

import csv
from django.http import HttpResponse

defsome_view(request):# Create the HttpResponse object with the appropriate CSV header.
    response = HttpResponse(
        content_type='text/csv',
        headers='Content-Disposition':'attachment; filename="somefilename.csv"',)

    writer = csv.writer(response)
    writer.writerow(['First row','Foo','Bar','Baz'])
    writer.writerow(['Second row','A','B','C','"Testing"',"Here's a quote"])return response

El código y los comentarios deben ser autoexplicativos, pero algunas cosas merecen una mención:

  • La respuesta obtiene un tipo MIME especial, texto / csv. Esto le dice a los navegadores que el documento es un archivo CSV, en lugar de un archivo HTML. Si deja esto desactivado, los navegadores probablemente interpretarán la salida como HTML, lo que dará como resultado un galimatías feo y aterrador en la ventana del navegador.
  • La respuesta obtiene un adicional Content-Disposition encabezado, que contiene el nombre del archivo CSV. Este nombre de archivo es arbitrario; llámalo como quieras. Los navegadores lo utilizarán en el cuadro de diálogo “Guardar como …”, etc.
  • Puede conectarse a la API de generación de CSV pasando response como el primer argumento para csv.writer. los csv.writer La función espera un objeto similar a un archivo, y HttpResponse los objetos encajan a la perfección.
  • Para cada fila de su archivo CSV, llame writer.writerow, pasándole un iterable.
  • El módulo CSV se encarga de las citas por usted, por lo que no tiene que preocuparse por escapar cadenas con comillas o comas. Aprobar writerow() tus cuerdas crudas, y hará lo correcto.

Transmisión de archivos CSV de gran tamaño

Cuando se trata de vistas que generan respuestas muy grandes, es posible que desee considerar el uso de Django StreamingHttpResponse en lugar de. Por ejemplo, al transmitir un archivo que tarda mucho en generarse, puede evitar que un equilibrador de carga interrumpa una conexión que, de otro modo, se habría agotado mientras el servidor generaba la respuesta.

En este ejemplo, hacemos un uso completo de los generadores de Python para manejar de manera eficiente el ensamblaje y la transmisión de un archivo CSV grande:

import csv

from django.http import StreamingHttpResponse

classEcho:"""An object that implements just the write method of the file-like
    interface.
    """defwrite(self, value):"""Write the value by returning it, instead of storing in a buffer."""return value

defsome_streaming_csv_view(request):"""A view that streams a large CSV file."""# Generate a sequence of rows. The range is based on the maximum number of# rows that can be handled by a single sheet in most spreadsheet# applications.
    rows =(["Row ".format(idx),str(idx)]for idx inrange(65536))
    pseudo_buffer = Echo()
    writer = csv.writer(pseudo_buffer)return StreamingHttpResponse((writer.writerow(row)for row in rows),
        content_type="text/csv",
        headers='Content-Disposition':'attachment; filename="somefilename.csv"',)

Usando el sistema de plantillas

Alternativamente, puede utilizar el Sistema de plantillas Django para generar CSV. Este es un nivel más bajo que usar el conveniente Python csv módulo, pero la solución se presenta aquí para que esté completa.

La idea aquí es pasar una lista de elementos a su plantilla y hacer que la plantilla muestre las comas en un for círculo.

Aquí hay un ejemplo, que genera el mismo archivo CSV que el anterior:

from django.http import HttpResponse
from django.template import loader

defsome_view(request):# Create the HttpResponse object with the appropriate CSV header.
    response = HttpResponse(
        content_type='text/csv'
        headers='Content-Disposition':'attachment; filename="somefilename.csv"',)# The data is hard-coded here, but you could load it from a database or# some other source.
    csv_data =(('First row','Foo','Bar','Baz'),('Second row','A','B','C','"Testing"',"Here's a quote"),)

    t = loader.get_template('my_template_name.txt')
    c ='data': csv_data
    response.write(t.render(c))return response

La única diferencia entre este ejemplo y el ejemplo anterior es que este usa la carga de plantillas en lugar del módulo CSV. El resto del código, como el content_type='text/csv' – es el mismo.

Luego, crea la plantilla my_template_name.txt, con este código de plantilla:

% for row in data %" row.0", "addslashes ", " row.2", "addslashes ", "addslashes "
% endfor %

Esta breve plantilla itera sobre los datos proporcionados y muestra una línea de CSV para cada fila. Usa el addslashes filtro de plantilla para garantizar que no haya problemas con las cotizaciones.

Otros formatos basados ​​en texto

Tenga en cuenta que aquí no hay mucho específico para CSV, solo el formato de salida específico. Puede utilizar cualquiera de estas técnicas para generar cualquier formato basado en texto con el que pueda soñar. También puede utilizar una técnica similar para generar datos binarios arbitrarios; ver Salida de archivos PDF con Django para un ejemplo.