Skip to content

Commit fad4736

Browse files
zedrtimgraham
authored andcommitted
Fixed #21179 -- Added a StreamingHttpResponse example for CSV files.
Thanks charettes for the suggestion.
1 parent 5840445 commit fad4736

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

docs/howto/outputting-csv.txt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,46 @@ For more information, see the Python documentation of the :mod:`csv` module.
7575
.. _`csv module's examples section`: http://docs.python.org/library/csv.html#examples
7676
.. _`python-unicodecsv module`: https://github.com/jdunck/python-unicodecsv
7777

78+
.. _streaming-csv-files:
79+
80+
Streaming large CSV files
81+
~~~~~~~~~~~~~~~~~~~~~~~~~
82+
83+
When dealing with views that generate very large responses, you might want to
84+
consider using Django's :class:`~django.http.StreamingHttpResponse` instead.
85+
For example, by streaming a file that takes a long time to generate you can
86+
avoid a load balancer dropping a connection that might have otherwise timed out
87+
while the server was generating the response.
88+
89+
In this example, we make full use of Python generators to efficiently handle
90+
the assembly and transmission of a large CSV file::
91+
92+
import csv
93+
94+
from django.utils.six.moves import range
95+
from django.http import StreamingHttpResponse
96+
97+
class Echo(object):
98+
"""An object that implements just the write method of the file-like
99+
interface.
100+
"""
101+
def write(self, value):
102+
"""Write the value by returning it, instead of storing in a buffer."""
103+
return value
104+
105+
def some_streaming_csv_view(request):
106+
"""A view that streams a large CSV file."""
107+
# Generate a sequence of rows. The range is based on the maximum number of
108+
# rows that can be handled by a single sheet in most spreadsheet
109+
# applications.
110+
rows = (["Row {0}".format(idx), str(idx)] for idx in range(65536))
111+
pseudo_buffer = Echo()
112+
writer = csv.writer(pseudo_buffer)
113+
response = StreamingHttpResponse((writer.writerow(row) for row in rows),
114+
content_type="text/csv")
115+
response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'
116+
return response
117+
78118
Using the template system
79119
=========================
80120

docs/ref/request-response.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,7 @@ StreamingHttpResponse objects
909909
The :class:`StreamingHttpResponse` class is used to stream a response from
910910
Django to the browser. You might want to do this if generating the response
911911
takes too long or uses too much memory. For instance, it's useful for
912-
generating large CSV files.
912+
:ref:`generating large CSV files <streaming-csv-files>`.
913913

914914
.. admonition:: Performance considerations
915915

0 commit comments

Comments
 (0)