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