Django使用StreamingHttpResponse實現(xiàn)流式響應(yīng)的實現(xiàn)示例
使用 StreamingHttpResponse 來實現(xiàn)流式響應(yīng),也就是將數(shù)據(jù)分塊返回給客戶端,而不是一次性返回全部內(nèi)容。這在處理大文件下載、實時數(shù)據(jù)推送等場景中非常實用。
一、基本原理與使用場景
StreamingHttpResponse 是 Django 提供的用于流式傳輸響應(yīng)的類,它不會一次性將所有響應(yīng)數(shù)據(jù)加載到內(nèi)存中,而是通過迭代器逐塊發(fā)送數(shù)據(jù),適合:
- 大文件下載(避免內(nèi)存溢出)
- 實時生成并返回數(shù)據(jù)(如實時日志、進度條更新)
- 服務(wù)器推送事件(SSE)等實時通信場景
二、基礎(chǔ)使用示例
1. 最簡單的流式響應(yīng)
先寫一個基礎(chǔ)示例,逐行返回文本數(shù)據(jù):
from django.http import StreamingHttpResponse
from django.views import View
import time
# 定義生成器函數(shù),用于逐塊生成數(shù)據(jù)
def stream_generator():
"""生成器函數(shù),逐行返回數(shù)據(jù)(模擬實時生成內(nèi)容)"""
for i in range(5):
# 模擬耗時操作(如讀取大文件、實時計算)
time.sleep(1)
# 每塊數(shù)據(jù)末尾加換行符,讓客戶端能實時看到
yield f"這是第 {i+1} 塊數(shù)據(jù)\n"
class StreamView(View):
def get(self, request):
# 創(chuàng)建 StreamingHttpResponse,傳入生成器
response = StreamingHttpResponse(stream_generator())
# 設(shè)置響應(yīng)頭,確??蛻舳税戳魈幚恚蛇x但推薦)
response['Content-Type'] = 'text/plain; charset=utf-8'
# 禁用緩存,確保數(shù)據(jù)實時推送
response['Cache-Control'] = 'no-cache'
# 添加流式傳輸 headers,禁用緩沖
# 注意:Transfer-Encoding 和 Connection 是 hop-by-hop headers,由 WSGI 服務(wù)器自動處理,不能在應(yīng)用層設(shè)置
# response['Cache-Control'] = 'no-cache, no-store, must-revalidate'
# response['Pragma'] = 'no-cache'
# response['Expires'] = '0'
# response['X-Accel-Buffering'] = 'no' # 禁用 Nginx 緩沖
# logger.info(f"[StreamingView] StreamingHttpResponse 已創(chuàng)建,headers 已配置用于流式傳輸")
return response
2. 大文件流式下載
這是更實用的場景,避免一次性讀取大文件到內(nèi)存:
from django.http import StreamingHttpResponse
from django.views import View
import os
def file_stream_generator(file_path, chunk_size=8192):
"""讀取文件并逐塊生成數(shù)據(jù)"""
with open(file_path, 'rb') as f:
while chunk := f.read(chunk_size):
yield chunk
class LargeFileDownloadView(View):
def get(self, request):
# 替換為你的大文件路徑
file_path = "/path/to/your/large_file.zip"
if not os.path.exists(file_path):
return HttpResponse("文件不存在", status=404)
# 獲取文件名
file_name = os.path.basename(file_path)
# 創(chuàng)建流式響應(yīng)
response = StreamingHttpResponse(
file_stream_generator(file_path),
content_type='application/octet-stream' # 二進制文件類型
)
# 設(shè)置下載頭,指定文件名
response['Content-Disposition'] = f'attachment; filename="{file_name}"'
# 設(shè)置分塊傳輸編碼
response['Transfer-Encoding'] = 'chunked'
return response
3. 實時 SSE(服務(wù)器推送事件)
適用于實時通知、進度展示等場景:
from django.http import StreamingHttpResponse
from django.views import View
import time
import json
def sse_generator():
"""生成 SSE 格式的實時數(shù)據(jù)"""
for i in range(10):
time.sleep(1)
# SSE 格式要求:data: 內(nèi)容\n\n
data = json.dumps({"progress": i * 10, "message": f"處理中 {i*10}%"})
yield f"data: {data}\n\n"
class SSEView(View):
def get(self, request):
response = StreamingHttpResponse(sse_generator())
# SSE 專用 Content-Type
response['Content-Type'] = 'text/event-stream'
# 禁用緩存和超時
response['Cache-Control'] = 'no-cache'
response['X-Accel-Buffering'] = 'no' # 禁用 nginx 緩沖(關(guān)鍵)
return response
三、關(guān)鍵注意事項
- 生成器必須是迭代器:
StreamingHttpResponse的參數(shù)必須是可迭代對象(如生成器函數(shù)),不能是普通列表(否則會一次性加載)。 - 禁用緩沖:
- 對于 Nginx 反向代理,需添加
response['X-Accel-Buffering'] = 'no',否則 Nginx 會緩沖數(shù)據(jù)直到生成器結(jié)束才推送。 - 對于 Apache,需配置
SetEnv no-gzip 1禁用壓縮緩沖。
- 對于 Nginx 反向代理,需添加
- 異常處理:生成器中如果出現(xiàn)異常,響應(yīng)會中斷,建議添加 try-except:
def stream_generator(): try: for i in range(5): time.sleep(1) yield f"第 {i+1} 塊數(shù)據(jù)\n" except Exception as e: yield f"出錯了:{str(e)}\n" - 不支持某些中間件:部分 Django 中間件(如
GZipMiddleware)會緩沖響應(yīng),導(dǎo)致流式失效,需排除這些中間件。
總結(jié)
StreamingHttpResponse核心是通過生成器逐塊返回數(shù)據(jù),避免一次性加載大量數(shù)據(jù)到內(nèi)存,適合大文件、實時數(shù)據(jù)場景。- 使用時需注意禁用緩沖(尤其是反向代理層),否則流式效果會失效。
- 不同場景需配置對應(yīng)的
Content-Type(如文件下載用application/octet-stream,SSE 用text/event-stream)。
補充:URL 配置(確保視圖可訪問)
在 urls.py 中添加路由:
from django.urls import path
from .views import StreamView, LargeFileDownloadView, SSEView
urlpatterns = [
path('stream/', StreamView.as_view(), name='stream'),
path('download-large-file/', LargeFileDownloadView.as_view(), name='download'),
path('sse/', SSEView.as_view(), name='sse'),
]
到此這篇關(guān)于Django使用StreamingHttpResponse實現(xiàn)流式響應(yīng)的實現(xiàn)示例的文章就介紹到這了,更多相關(guān)Django流式響應(yīng)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用python-cv2實現(xiàn)Harr+Adaboost人臉識別的示例
這篇文章主要介紹了使用python-cv2實現(xiàn)Harr+Adaboost人臉識別的示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
python使用tcp實現(xiàn)局域網(wǎng)內(nèi)文件傳輸
這篇文章主要介紹了python使用tcp實現(xiàn)局域網(wǎng)內(nèi)文件傳輸,文件包括文本,圖片,視頻等,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-07-07
Python處理圖像并生成JSONL元數(shù)據(jù)文件
JSONL是一種輕量級的數(shù)據(jù)序列化格式,由一系列獨立的?JSON?對象組成,本文主要為大家介紹了Python如何處理圖像并生成JSONL元數(shù)據(jù)文件,感興趣的可以了解下2025-05-05
提高Python生產(chǎn)力的五個Jupyter notebook插件
Jupyter Notebook 因其可用性和實用性而成為數(shù)據(jù)分析和機器學(xué)習(xí)模型領(lǐng)域最流行的 IDE,它也是很多數(shù)據(jù)初學(xué)者的首選 IDE。它最具特色的是,擁有豐富的插件、擴展數(shù)據(jù)處理能力和提升工作效率2021-11-11
pandas 數(shù)據(jù)索引與選取的實現(xiàn)方法
這篇文章主要介紹了pandas 數(shù)據(jù)索引與選取的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06
Pytorch基本變量類型FloatTensor與Variable用法
今天小編就為大家分享一篇Pytorch基本變量類型FloatTensor與Variable用法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01

