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 flask import Blueprint, jsonify, request, abort v1 = Blueprint("users_v1", __name__) v2 = Blueprint("users_v2", __name__)
Versioning a Flask API with Blueprints
api versioning
blueprints
rest
Intermediate
7 steps
php
<?php namespace App\Http\Controllers;
Streaming a filtered CSV export in Laravel
streaming
csv-export
query-builder
Intermediate
9 steps
python
import time import threading from enum import Enum from functools import wraps
Building a circuit breaker in Python
circuit-breaker
resilience
decorators
Advanced
7 steps
python
from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector from django.core.cache import cache from django.db.models import F from django.http import JsonResponse
Ranked full-text search in Django
full-text-search
debouncing
caching
Advanced
9 steps
python
import os from datetime import timedelta
Class-based config in a Flask app factory
configuration
app-factory
inheritance
Intermediate
7 steps
python
import time from flask import Flask, g, request
Timing requests with Flask hooks
middleware
request-lifecycle
instrumentation
Intermediate
5 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.