Класс StreamingHttpResponse

Класс StreamingHttpResponse применяется для отправки больших объемов данных клиенту частями, без загрузки всего содержимого в память. Этот класс принимает итератор или генератор, который будет выдавать строки или байтовые данные для отправки. Класс полезен при генерации больших CSV-файлов, трансляции видео или создании событий в реальном времени. Класс не поддерживает заголовок Content-Length, так как размер заранее неизвестен.

Синтаксис

pythonfrom django.http import StreamingHttpResponse

response = StreamingHttpResponse(streaming_content, status=200, headers=None)

Параметры конструктора:

Пример . №1: генерация CSV файла

Давайте создадим представление, которое генерирует CSV файл из больших данных с помощью потоковой передачи:

pythonimport 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

Результат выполнения кода:

python"CSV файл сгенерирован и отправлен частями"

Пример . №2: потоковая передача текста

Давайте создадим представление, которое передает данные генератора по частям:

pythonimport 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

Результат выполнения кода:

python"Data chunk 0\nData chunk 1\nData chunk 2\n..."

Пример . №3: генерация больших JSON данных

Давайте создадим представление, которое передает большие JSON данные частями:

pythonimport 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

Результат выполнения кода:

python"[{\"id\": 1, \"title\": \"First article\", \"status\": \"published\"}, ...]"

Смотрите также

  • класс HttpResponse,
    который используется для обычной отправки данных
  • класс FileResponse,
    который используется для отправки файлов
  • класс JsonResponse,
    который используется для отправки JSON данных
  • атрибут content,
    который содержит содержимое ответа