Cả 3 đều là response object, chọn cái nào tuỳ vào kiểu dữ liệu và kích thước.
HttpResponse(content, content_type=...) buffer toàn bộ body trong RAM rồi trả — hợp với HTML, text, binary nhỏ. JsonResponse({...}) là wrapper quanh HttpResponse với content_type='application/json' cộng json.dumps — hợp với API trả dict; nếu trả list phải set safe=False. StreamingHttpResponse(generator) không buffer mà stream từng chunk — hợp với CSV export, file lớn, server-sent events.
from django.http import StreamingHttpResponse
import csv
def export_csv(request):
def rows():
yield ['id', 'title']
for p in Post.objects.iterator(chunk_size=2000):
yield [p.id, p.title]
pseudo = (','.join(map(str, r)) + '\n' for r in rows())
response = StreamingHttpResponse(pseudo, content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="posts.csv"'
return responseHai chỗ dễ vấp: streaming response không nén được qua middleware GZip (Django giữ chunked transfer), nên phải nén ở nginx hoặc gửi file đã nén sẵn.
Còn JsonResponse mặc định escape Unicode — set json_dumps_params={'ensure_ascii': False} để giữ UTF-8 đọc được.
All three are response objects; the choice depends on data shape and size:
HttpResponse(content, content_type=...)— buffers the whole body in RAM and returns it. Fits HTML/text/small binary.JsonResponse({...})— wrapsHttpResponsewithcontent_type='application/json'+json.dumps. Fits APIs returning dicts; needssafe=Falsefor lists.StreamingHttpResponse(generator)— no buffering, streams chunk by chunk. Fits CSV export, big files, server-sent events.
from django.http import StreamingHttpResponse
import csv
def export_csv(request):
def rows():
yield ['id', 'title']
for p in Post.objects.iterator(chunk_size=2000):
yield [p.id, p.title]
pseudo = (','.join(map(str, r)) + '\n' for r in rows())
response = StreamingHttpResponse(pseudo, content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="posts.csv"'
return responsePitfall: Streaming is not compressed by GZip middleware (Django keeps chunked transfer); compress at nginx or pre-gzip the file.
And JsonResponse escapes Unicode by default → pass json_dumps_params={'ensure_ascii': False} for friendly UTF-8.