W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
當(dāng)一個(gè)用戶上傳文件時(shí),Django 會(huì)把文件數(shù)據(jù)傳遞給 ?upload handler
? —— 這是一個(gè)很小的類,它用來在上傳時(shí)處理文件數(shù)據(jù)。上傳處理模塊最初定義在 ?FILE_UPLOAD_HANDLERS
?里,默認(rèn)為:
["django.core.files.uploadhandler.MemoryFileUploadHandler",
"django.core.files.uploadhandler.TemporaryFileUploadHandler"]
?
MemoryFileUploadHandler
?和 ?TemporaryFileUploadHandler
?提供 Django 默認(rèn)文件上傳行為,小文件讀入內(nèi)存,大文件存在磁盤上。
你可以編寫自定義的 ?handlers
?來自定義 Django 如何處理文件。比如,你可以使用自定義的 ?handlers
?來強(qiáng)制處理用戶層面的配額,動(dòng)態(tài)壓縮數(shù)據(jù),渲染進(jìn)度條,甚至可以將數(shù)據(jù)發(fā)送到其他存儲(chǔ)地址而不是本地。
在保存上傳的文件之前,數(shù)據(jù)需要保存到某處。
默認(rèn)情況下,如果上傳的文件小于2.5兆,Django 將把文件的所有內(nèi)容保存到內(nèi)存里。這意味著保存文件只涉及從內(nèi)存中讀取和寫入磁盤,因此這很快。
但如果上傳的文件很大,Django 會(huì)把文件寫入系統(tǒng)臨時(shí)目錄的臨時(shí)文件里存儲(chǔ)。在類 Unix 平臺(tái)里這意味著 Django 會(huì)生成一個(gè)類似名為 ?/tmp/tmpzfp6I6.upload
? 的文件。如果上傳的文件非常大,你可以查看這個(gè)文件的大小增長,因?yàn)?Django 將數(shù)據(jù)流式傳輸?shù)酱疟P上。
有時(shí)候某些視圖需要不同的上傳行為。在這些例子里,你可以基于每個(gè)請求覆蓋上傳處理程序。默認(rèn)情況下,這個(gè)列表將包含由 ?FILE_UPLOAD_HANDLERS
?設(shè)置的上傳處理程序,但你可以像修改其他列表一樣修改這個(gè)列表。
比如,假設(shè)你正在編寫 ?ProgressBarUploadHandler
?,來提供在上傳過程中的反饋給 ?Ajax widget
?。你需要添加這個(gè)處理程序到你的上傳處理模塊:
request.upload_handlers.insert(0, ProgressBarUploadHandler(request))
你或許想在這里使用 ?list.insert()
? (而不是 ?append()
? ),因?yàn)檫M(jìn)度條處理程序需要在其他處理程序之前使用。記住,上傳處理程序是按順序處理的。
如果你想完全替換上傳處理程序,你需要指定新列表:
request.upload_handlers = [ProgressBarUploadHandler(request)]
你只能在訪問 ?request.POST
? 或 ?request.FILES
? 之前修改上傳處理程序,開始上傳處理后修改上傳處理程序沒有意義。如果你從讀取 ?request.POST
? 或 ?request.FILES
? 之后嘗試修改 ?request.upload_handlers
? ,Django 會(huì)報(bào)錯(cuò)。
因此,你要盡早在視圖里修改上傳處理程序。
而且, ?request.POST
? 由 ?CsrfViewMiddleware
?訪問,默認(rèn)情況下已開啟。這意味著你需要在視圖上使用 ?csrf_exempt()
? 來允許你改變上傳處理程序。然后你需要在實(shí)際處理請求的函數(shù)上使用 ?csrf_protect()
? 。注意這可能會(huì)讓處理程序在 CSRF 檢測完成之前開始接受文件上傳。示例:
from django.views.decorators.csrf import csrf_exempt, csrf_protect
@csrf_exempt
def upload_file_view(request):
request.upload_handlers.insert(0, ProgressBarUploadHandler(request))
return _upload_file_view(request)
@csrf_protect
def _upload_file_view(request):
... # Process request
如果你使用的是基于類的視圖,你需要在其 ?csrf_exempt()
? 方法上使用 ?dispatch()
?,并在實(shí)際處理請求的方法上使用 ?csrf_protect()
?。示例代碼:
from django.utils.decorators import method_decorator
from django.views import View
from django.views.decorators.csrf import csrf_exempt, csrf_protect
@method_decorator(csrf_exempt, name='dispatch')
class UploadFileView(View):
def setup(self, request, *args, **kwargs):
request.upload_handlers.insert(0, ProgressBarUploadHandler(request))
super().setup(request, *args, **kwargs)
@method_decorator(csrf_protect)
def post(self, request, *args, **kwargs):
... # Process request
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: