python
49 lines · 7 steps
Streaming a CSV export in Django
A class-based view streams a large query as CSV without buffering the whole file in memory.
Explained by
highlit
1import csv
2
3from django.http import StreamingHttpResponse
4from django.utils.timezone import now
5from django.views import View
6
7from .models import Order
8
9
10class Echo:
11 def write(self, value):
12 return value
13
14
15class OrderExportView(View):
16 columns = [
17 ("id", "Order ID"),
18 ("customer_email", "Customer"),
19 ("total", "Total"),
20 ("status", "Status"),
21 ("created_at", "Created"),
22 ]
23
24 def get_queryset(self, request):
25 qs = Order.objects.select_related("customer").order_by("created_at")
26 status = request.GET.get("status")
27 if status:
28 qs = qs.filter(status=status)
29 since = request.GET.get("since")
30 if since:
31 qs = qs.filter(created_at__date__gte=since)
32 return qs
33
34 def rows(self, request):
35 writer = csv.writer(Echo())
36 yield writer.writerow(label for _, label in self.columns)
37 queryset = self.get_queryset(request)
38 for order in queryset.iterator(chunk_size=2000):
39 yield writer.writerow(
40 getattr(order, field) for field, _ in self.columns
41 )
42
43 def get(self, request, *args, **kwargs):
44 filename = f"orders-{now():%Y%m%d-%H%M%S}.csv"
45 response = StreamingHttpResponse(
46 self.rows(request), content_type="text/csv"
47 )
48 response["Content-Disposition"] = f'attachment; filename="{filename}"'
49 return response
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Streaming responses let you send arbitrarily large exports without holding the full payload in memory.
- 2A pseudo-buffer that just returns what it's given lets csv.writer produce strings you can yield one at a time.
- 3Pairing an iterator queryset with generator rows keeps both the database and the response streaming in chunks.
Related explainers
python
from fastapi import FastAPI, WebSocket, WebSocketDisconnect app = FastAPI()
Building a WebSocket chat with FastAPI
websockets
broadcast
connection-management
Intermediate
9 steps
python
import time import uuid from django.utils.deprecation import MiddlewareMixin
Attaching per-request context in Django
middleware
request lifecycle
multi-tenancy
Intermediate
7 steps
python
import random from typing import Iterator, List
How reservoir sampling picks k items
reservoir-sampling
streaming
randomness
Intermediate
5 steps
python
import secrets from django.contrib.auth import authenticate, login from django.core.cache import cache
Two-factor login with OTP in Django
two-factor-auth
one-time-passwords
caching
Intermediate
9 steps
python
import re from functools import total_ordering from typing import Optional
Parsing and comparing semantic versions
regex
operator-overloading
sorting
Intermediate
7 steps
python
from typing import Any, Sequence, Mapping def render_markdown_table(
Rendering an aligned Markdown table in Python
string formatting
data transformation
closures
Intermediate
8 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/streaming-a-csv-export-in-django-explained-python-e76b/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.