Класс StreamingHttpResponse
Класс StreamingHttpResponse применяется для отправки больших объемов данных клиенту частями, без загрузки всего содержимого в память. Этот класс принимает итератор или генератор, который будет выдавать строки или байтовые данные для отправки. Класс полезен при генерации больших CSV-файлов, трансляции видео или создании событий в реальном времени. Класс не поддерживает заголовок Content-Length, так как размер заранее неизвестен.
Синтаксис
from django.http import StreamingHttpResponse
response = StreamingHttpResponse(streaming_content, status=200, headers=None)
Параметры конструктора:
-
streaming_content- итератор или генератор, выдающий строки или байты -
status- HTTP статус код (по умолчанию200) -
headers- словарь с дополнительными заголовками
Пример . №1: генерация CSV файла
Давайте создадим представление, которое генерирует CSV файл из больших данных с помощью потоковой передачи:
import csv
from django.http import StreamingHttpResponse
from myapp.models import Article
class Echo:
"""
Класс-обертка для записи CSV через генератор.
"""
def write(self, value):
"""
Возвращает переданное значение как есть.
"""
return value
def stream_csv(request):
"""
Представление для потоковой генерации CSV.
"""
# Получаем все статьи
articles = Article.objects.all().values('title', 'status', 'created_at')
# Генератор для выдачи строк CSV
def generate_csv(articles):
"""
Генерирует CSV строки из QuerySet.
"""
echo_writer = csv.writer(Echo())
# Заголовки CSV
yield echo_writer.write(['Title', 'Status', 'Created At'])
for article in articles:
row = [
article['title'],
article['status'],
article['created_at'].strftime('%Y-%m-%d')
]
yield echo_writer.write(row)
# Создаем потоковый ответ
response = StreamingHttpResponse(
generate_csv(articles),
headers={'Content-Type': 'text/csv'}
)
response['Content-Disposition'] = 'attachment; filename="articles.csv"'
return response
Результат выполнения кода:
"CSV файл сгенерирован и отправлен частями"
Пример . №2: потоковая передача текста
Давайте создадим представление, которое передает данные генератора по частям:
import time
from django.http import StreamingHttpResponse
def stream_data(request):
"""
Представление для потоковой передачи текстовых данных.
"""
def data_generator():
"""
Генератор, выдающий данные частями.
"""
for i in range(10):
# Имитируем долгую обработку
time.sleep(0.5)
yield f"Data chunk {i}\n"
response = StreamingHttpResponse(
data_generator(),
headers={'Content-Type': 'text/plain'}
)
return response
Результат выполнения кода:
"Data chunk 0\nData chunk 1\nData chunk 2\n..."
Пример . №3: генерация больших JSON данных
Давайте создадим представление, которое передает большие JSON данные частями:
import json
from django.http import StreamingHttpResponse
from myapp.models import Article
def stream_json(request):
"""
Представление для потоковой генерации JSON.
"""
articles = Article.objects.all().values('id', 'title', 'status')
def generate_json(articles):
"""
Генерирует JSON из QuerySet по частям.
"""
yield '['
first = True
for article in articles:
if not first:
yield ','
yield json.dumps(article)
first = False
yield ']'
response = StreamingHttpResponse(
generate_json(articles),
headers={'Content-Type': 'application/json'}
)
return response
Результат выполнения кода:
"[{\"id\": 1, \"title\": \"First article\", \"status\": \"published\"}, ...]"
Смотрите также
-
класс
HttpResponse,
который используется для обычной отправки данных -
класс
FileResponse,
который используется для отправки файлов -
класс
JsonResponse,
который используется для отправки JSON данных -
атрибут
content,
который содержит содержимое ответа