Factored out django.core.management ACTION_MAPPING into DEFAULT_ACTION_MAPPING, so...
[fdr-django.git] / docs / outputting_csv.txt
blob3f95b3600daae275c17355781913d4993b4e273d
1 ==========================
2 Outputting CSV with Django
3 ==========================
5 This document explains how to output CSV (Comma Separated Values) dynamically
6 using Django views.
8 To do this, you can either use the `Python CSV library`_ or the Django template
9 system.
11 .. _Python CSV library: http://www.python.org/doc/current/lib/module-csv.html
13 Using the Python CSV library
14 ============================
16 Python comes with a CSV library, ``csv``. The key to using it with Django is
17 that the ``csv`` module's CSV-creation capability acts on file-like objects,
18 and Django's ``HttpResponse`` objects are file-like objects.
20 .. admonition:: Note
22     For more information on ``HttpResponse`` objects, see
23     `Request and response objects`_.
25     For more information on the CSV library, see the `CSV library docs`_.
27     .. _Request and response objects: http://www.djangoproject.com/documentation/request_response/
28     .. _CSV library docs: http://www.python.org/doc/current/lib/module-csv.html
30 Here's an example::
32     import csv
33     from django.utils.httpwrappers import HttpResponse
35     def some_view(request):
36         # Create the HttpResponse object with the appropriate CSV header.
37         response = HttpResponse(mimetype='text/csv')
38         response['Content-Disposition'] = 'attachment; filename=somefilename.csv'
40         writer = csv.writer(response)
41         writer.writerow(['First row', 'Foo', 'Bar', 'Baz'])
42         writer.writerow(['Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"])
44         return response
46 The code and comments should be self-explanatory, but a few things deserve a
47 mention:
49     * The response gets a special mimetype, ``text/csv``. This tells
50       browsers that the document is a CSV file, rather than an HTML file. If
51       you leave this off, browsers will probably interpret the output as HTML,
52       which would result in ugly, scary gobbledygook in the browser window.
54     * The response gets an additional ``Content-Disposition`` header, which
55       contains the name of the CSV file. This filename is arbitrary: Call it
56       whatever you want. It'll be used by browsers in the "Save as..."
57       dialogue, etc.
59     * Hooking into the CSV-generation API is easy: Just pass ``response`` as
60       the first argument to ``csv.writer``. The ``csv.writer`` function expects
61       a file-like object, and ``HttpResponse`` objects fit the bill.
63     * For each row in your CSV file, call ``writer.writerow``, passing it an
64       iterable object such as a list or tuple.
66     * The CSV module takes care of quoting for you, so you don't have to worry
67       about escaping strings with quotes or commas in them. Just pass
68       ``writerow()`` your raw strings, and it'll do the right thing.
70 Using the template system
71 =========================
73 Alternatively, you can use the `Django template system`_ to generate CSV. This
74 is lower-level than using the convenient CSV, but the solution is presented
75 here for completeness.
77 The idea here is to pass a list of items to your template, and have the
78 template output the commas in a ``{% for %}`` loop.
80 Here's an example, which generates the same CSV file as above::
82     from django.utils.httpwrappers import HttpResponse
83     from django.core.template import loader, Context
85     def some_view(request):
86         # Create the HttpResponse object with the appropriate CSV header.
87         response = HttpResponse(mimetype='text/csv')
88         response['Content-Disposition'] = 'attachment; filename=somefilename.csv'
90         # The data is hard-coded here, but you could load it from a database or
91         # some other source.
92         csv_data = (
93             ('First row', 'Foo', 'Bar', 'Baz'),
94             ('Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"),
95         )
97         t = loader.get_template('my_template_name')
98         c = Context({
99             'data': csv_data,
100         })
101         response.write(t.render(c))
102         return response
104 The only difference between this example and the previous example is that this
105 one uses template loading instead of the CSV module. The rest of the code --
106 such as the ``mimetype='text/csv'`` -- is the same.
108 Then, create the template ``my_template_name``, with this template code::
110     {% for row in data %}"{{ row.0|addslashes }}", "{{ row.1|addslashes }}", "{{ row.2|addslashes }}", "{{ row.3|addslashes }}", "{{ row.4|addslashes }}"
111     {% endfor %}
113 This template is quite basic. It just iterates over the given data and displays
114 a line of CSV for each row. It uses the `addslashes template filter`_ to ensure
115 there aren't any problems with quotes. If you can be certain your data doesn't
116 have single or double quotes in it, you can remove the ``addslashes`` filters.
118 .. _Django template system: http://www.djangoproject.com/documentation/templates/
119 .. _addslashes template filter: http://www.djangoproject.com/documentation/templates/#addslashes