jazzband / django-downloadview

Serve files with Django.
https://django-downloadview.readthedocs.io
Other
380 stars 58 forks source link

CSVDownloadView for easy dynamic CSV generation #78

Open benoitbryon opened 10 years ago

benoitbryon commented 10 years ago

Generating CSV files dynamically is a common use case for VirtualDownloadView. Perhaps a generic view could provide base scenario.

benoitbryon commented 10 years ago

Consider this snippet by @brunobord:

import csv
import cStringIO as StringIO

from django_downloadview import VirtualDownloadView, DownloadMixin, VirtualFil

class CsvDownloadMixin(DownloadMixin):
    """CSV download helper."""
    delimiter = ";"
    quotechar = '"'
    quoting = csv.QUOTE_MINIMAL

    def get_filename(self):
        "Override this if you need a specific filename"
        return "download.csv"

    def get_header(self):
        """Return a list of cells to be written into the header.

        Please note that this row should be a list of unicode-ready strings.

        """
        raise NotImplementedError("You need to write the get_header() method")

    def get_rows(self):
        """Return a list of rows to be written into the body of the CSV file.

        Please note that each row should be a list of unicode-ready strings.

        """
        raise NotImplementedError("You need to write the get_rows() method")

    def write_header(self, csvwriter):
        """Write headers in the CSV file."""
        csvwriter.writerow(self.get_header())

    def write_rows(self, csvwriter):
        """Write rows in the CSV file."""
        for row in self.get_rows():
            csvwriter.writerow(row)

    def get_file(self):
        """Return a VirtualFile to be downloaded as CSV."""
        csvfile = StringIO.StringIO()
        csvwriter = csv.writer(
            csvfile, delimiter=self.delimiter, quotechar=self.quotechar,
            quoting=self.quoting)
        self.write_header(csvwriter)
        self.write_rows(csvwriter)
        return VirtualFile(csvfile, self.get_filename())

class CsvDownloadView(CsvDownloadMixin, VirtualDownloadView):
    pass
benoitbryon commented 10 years ago

The implementation should use generators. See http://django-downloadview.readthedocs.org/en/1.5/views/virtual.html#stream-generated-content