PageRenderTime 100ms CodeModel.GetById 38ms app.highlight 2ms RepoModel.GetById 24ms app.codeStats 0ms

/docs/howto/outputting-csv.txt

https://code.google.com/p/mango-py/
Plain Text | 137 lines | 100 code | 37 blank | 0 comment | 0 complexity | cdbb540a8440f27a11089a653b42c8fa MD5 | raw file
  1==========================
  2Outputting CSV with Django
  3==========================
  4
  5This document explains how to output CSV (Comma Separated Values) dynamically
  6using Django views. To do this, you can either use the `Python CSV library`_ or
  7the Django template system.
  8
  9.. _Python CSV library: http://docs.python.org/library/csv.html
 10
 11Using the Python CSV library
 12============================
 13
 14Python comes with a CSV library, ``csv``. The key to using it with Django is
 15that the ``csv`` module's CSV-creation capability acts on file-like objects, and
 16Django's :class:`~django.http.HttpResponse` objects are file-like objects.
 17
 18Here's an example::
 19
 20    import csv
 21    from django.http import HttpResponse
 22
 23    def some_view(request):
 24        # Create the HttpResponse object with the appropriate CSV header.
 25        response = HttpResponse(mimetype='text/csv')
 26        response['Content-Disposition'] = 'attachment; filename=somefilename.csv'
 27
 28        writer = csv.writer(response)
 29        writer.writerow(['First row', 'Foo', 'Bar', 'Baz'])
 30        writer.writerow(['Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"])
 31
 32        return response
 33
 34The code and comments should be self-explanatory, but a few things deserve a
 35mention:
 36
 37    * The response gets a special MIME type, ``text/csv``. This tells
 38      browsers that the document is a CSV file, rather than an HTML file. If
 39      you leave this off, browsers will probably interpret the output as HTML,
 40      which will result in ugly, scary gobbledygook in the browser window.
 41
 42    * The response gets an additional ``Content-Disposition`` header, which
 43      contains the name of the CSV file. This filename is arbitrary; call it
 44      whatever you want. It'll be used by browsers in the "Save as..."
 45      dialogue, etc.
 46
 47    * Hooking into the CSV-generation API is easy: Just pass ``response`` as the
 48      first argument to ``csv.writer``. The ``csv.writer`` function expects a
 49      file-like object, and :class:`~django.http.HttpResponse` objects fit the
 50      bill.
 51
 52    * For each row in your CSV file, call ``writer.writerow``, passing it an
 53      iterable object such as a list or tuple.
 54
 55    * The CSV module takes care of quoting for you, so you don't have to worry
 56      about escaping strings with quotes or commas in them. Just pass
 57      ``writerow()`` your raw strings, and it'll do the right thing.
 58
 59Handling Unicode
 60~~~~~~~~~~~~~~~~
 61
 62Python's ``csv`` module does not support Unicode input. Since Django uses
 63Unicode internally this means strings read from sources such as
 64:class:`~django.http.HttpRequest` are potentially problematic. There are a few
 65options for handling this:
 66
 67    * Manually encode all Unicode objects to a compatible encoding.
 68
 69    * Use the ``UnicodeWriter`` class provided in the `csv module's examples
 70      section`_.
 71
 72    * Use the `python-unicodecsv module`_, which aims to be a drop-in
 73      replacement for ``csv`` that gracefully handles Unicode.
 74
 75For more information, see the Python `CSV File Reading and Writing`_
 76documentation.
 77
 78.. _`csv module's examples section`: http://docs.python.org/library/csv.html#examples
 79.. _`python-unicodecsv module`: https://github.com/jdunck/python-unicodecsv
 80.. _`CSV File Reading and Writing`: http://docs.python.org/library/csv.html
 81
 82Using the template system
 83=========================
 84
 85Alternatively, you can use the :doc:`Django template system </topics/templates>`
 86to generate CSV. This is lower-level than using the convenient Python ``csv``
 87module, but the solution is presented here for completeness.
 88
 89The idea here is to pass a list of items to your template, and have the
 90template output the commas in a :ttag:`for` loop.
 91
 92Here's an example, which generates the same CSV file as above::
 93
 94    from django.http import HttpResponse
 95    from django.template import loader, Context
 96
 97    def some_view(request):
 98        # Create the HttpResponse object with the appropriate CSV header.
 99        response = HttpResponse(mimetype='text/csv')
100        response['Content-Disposition'] = 'attachment; filename=somefilename.csv'
101
102        # The data is hard-coded here, but you could load it from a database or
103        # some other source.
104        csv_data = (
105            ('First row', 'Foo', 'Bar', 'Baz'),
106            ('Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"),
107        )
108
109        t = loader.get_template('my_template_name.txt')
110        c = Context({
111            'data': csv_data,
112        })
113        response.write(t.render(c))
114        return response
115
116The only difference between this example and the previous example is that this
117one uses template loading instead of the CSV module. The rest of the code --
118such as the ``mimetype='text/csv'`` -- is the same.
119
120Then, create the template ``my_template_name.txt``, with this template code:
121
122.. code-block:: html+django
123
124    {% for row in data %}"{{ row.0|addslashes }}", "{{ row.1|addslashes }}", "{{ row.2|addslashes }}", "{{ row.3|addslashes }}", "{{ row.4|addslashes }}"
125    {% endfor %}
126
127This template is quite basic. It just iterates over the given data and displays
128a line of CSV for each row. It uses the :tfilter:`addslashes` template filter to
129ensure there aren't any problems with quotes.
130
131Other text-based formats
132========================
133
134Notice that there isn't very much specific to CSV here -- just the specific
135output format. You can use either of these techniques to output any text-based
136format you can dream of. You can also use a similar technique to generate
137arbitrary binary data; see :doc:`/howto/outputting-pdf` for an example.