上傳檔案與上傳處理器¶
上傳檔案¶
在檔案上傳期間,實際的檔案資料會儲存在 request.FILES
中。這個字典中的每個條目都是一個 UploadedFile
物件(或子類別)——它是上傳檔案的包裝器。您通常會使用以下方法之一來存取上傳的內容:
- UploadedFile.read()¶
從檔案讀取整個上傳資料。使用此方法時請小心:如果上傳的檔案很大,嘗試將其讀入記憶體可能會使您的系統不堪負荷。您可能會想改用
chunks()
;請見下方。
- UploadedFile.multiple_chunks(chunk_size=None)¶
如果上傳的檔案大到需要分成多個區塊讀取,則傳回
True
。預設情況下,任何大於 2.5 MB 的檔案都算太大,但這是可以設定的;請見下方。
- UploadedFile.chunks(chunk_size=None)¶
一個產生器,傳回檔案的區塊。如果
multiple_chunks()
為True
,您應該在迴圈中使用此方法,而不是read()
。實際上,最簡單的方法通常是一直使用
chunks()
。迴圈遍歷chunks()
而不是使用read()
可以確保大型檔案不會使您系統的記憶體不堪負荷。
以下是 UploadedFile
的一些有用屬性:
- UploadedFile.name¶
上傳檔案的名稱(例如
my_file.txt
)。
- UploadedFile.size¶
上傳檔案的大小,以位元組為單位。
- UploadedFile.content_type¶
與檔案一起上傳的 content-type 標頭(例如 text/plain 或 application/pdf)。與使用者提供的任何資料一樣,您不應相信上傳的檔案實際上是這種型別。您仍然需要驗證檔案是否包含 content-type 標頭聲稱的內容 –「信任但要驗證」。
- UploadedFile.content_type_extra¶
一個字典,其中包含傳遞到
content-type
標頭的額外參數。這通常由服務提供,例如 Google App Engine,它們會攔截並代表您處理檔案上傳。因此,您的處理常式可能不會收到上傳的檔案內容,而是收到檔案的 URL 或其他指標(請參閱 RFC 2388)。
- UploadedFile.charset¶
對於 text/* content-type,由瀏覽器提供的字元集(即
utf8
)。同樣,「信任但要驗證」是這裡的最佳策略。
注意
就像一般的 Python 檔案一樣,您可以透過迭代上傳的檔案來逐行讀取檔案。
for line in uploadedfile:
do_something_with(line)
使用 通用換行符號 來分割行。以下被識別為一行的結尾:Unix 的行尾慣例 '\n'
、Windows 慣例 '\r\n'
和舊的 Macintosh 慣例 '\r'
。
UploadedFile
的子類別包括:
- class TemporaryUploadedFile[原始碼]¶
上傳到臨時位置的檔案(即串流到磁碟)。此類別由
TemporaryFileUploadHandler
使用。除了UploadedFile
中的方法之外,它還有一個額外的方法:
- class InMemoryUploadedFile[原始碼]¶
上傳到記憶體的檔案(即串流到記憶體)。此類別由
MemoryFileUploadHandler
使用。
內建上傳處理器¶
MemoryFileUploadHandler
和 TemporaryFileUploadHandler
共同提供了 Django 的預設檔案上傳行為,即將小型檔案讀入記憶體,將大型檔案讀到磁碟。它們位於 django.core.files.uploadhandler
中。
將上傳串流到記憶體中的檔案上傳處理器(用於小型檔案)。
使用 TemporaryUploadedFile
將資料串流到臨時檔案的檔案上傳處理器。
編寫自訂上傳處理器¶
所有檔案上傳處理器都應該是 django.core.files.uploadhandler.FileUploadHandler
的子類別。您可以在任何您希望的地方定義上傳處理器。
必要方法¶
自訂檔案上傳處理器必須定義以下方法:
- FileUploadHandler.receive_data_chunk(raw_data, start)[原始碼]¶
接收檔案上傳的「資料塊」。
raw_data
是一個包含上傳資料的位元組字串。start
是此raw_data
資料塊在檔案中的起始位置。您回傳的資料將會被傳遞到後續上傳處理器的
receive_data_chunk
方法中。透過這種方式,一個處理器可以作為其他處理器的「篩選器」。從
receive_data_chunk
回傳None
可以阻止後續上傳處理器處理此資料塊。如果您要自行儲存上傳的資料,並且不希望後續的處理器儲存資料的副本,這會很有用。如果您引發
StopUpload
或SkipFile
例外,則上傳將會中止或該檔案將會被完全略過。
選用方法¶
自訂上傳處理器也可以定義以下任何選用方法或屬性
- FileUploadHandler.chunk_size¶
Django 應該儲存到記憶體並傳遞給處理器的「資料塊」大小(以位元組為單位)。也就是說,這個屬性控制傳遞給
FileUploadHandler.receive_data_chunk
的資料塊大小。為了獲得最佳效能,資料塊大小應可被
4
整除,且不應超過 2 GB(231 位元組)。當多個處理器提供多個資料塊大小時,Django 將會使用任何處理器定義的最小資料塊大小。預設值為 64*210 位元組,即 64 KB。
- FileUploadHandler.new_file(field_name, file_name, content_type, content_length, charset, content_type_extra)[原始碼]¶
發出信號表示新的檔案上傳即將開始的回呼函數。這會在任何資料被傳遞到任何上傳處理器之前呼叫。
field_name
是檔案<input>
欄位的字串名稱。file_name
是瀏覽器提供的檔案名稱。content_type
是瀏覽器提供的 MIME 類型,例如'image/jpeg'
。content_length
是瀏覽器提供的影像長度。有時這不會被提供,並且會是None
。charset
是瀏覽器提供的字元集(例如utf8
)。與content_length
一樣,有時這不會被提供。content_type_extra
是來自content-type
標頭關於檔案的額外資訊。請參閱UploadedFile.content_type_extra
。此方法可能會引發
StopFutureHandlers
例外,以防止後續處理器處理此檔案。
- FileUploadHandler.handle_raw_input(input_data, META, content_length, boundary, encoding)[原始碼]¶
允許處理器完全覆寫原始 HTTP 輸入的解析。
input_data
是一個支援read()
的類檔案物件。META
與request.META
是相同的物件。content_length
是input_data
中資料的長度。不要從input_data
讀取超過content_length
位元組的資料。boundary
是此請求的 MIME 分界符。encoding
是請求的編碼。如果您希望上傳處理繼續,則回傳
None
;如果您希望直接回傳適合請求的新資料結構,則回傳(POST, FILES)
的元組。