上傳檔案與上傳處理器

上傳檔案

class UploadedFile[原始碼]

在檔案上傳期間,實際的檔案資料會儲存在 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/plainapplication/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 中的方法之外,它還有一個額外的方法:

TemporaryUploadedFile.temporary_file_path()[原始碼]

傳回臨時上傳檔案的完整路徑。

class InMemoryUploadedFile[原始碼]

上傳到記憶體的檔案(即串流到記憶體)。此類別由 MemoryFileUploadHandler 使用。

內建上傳處理器

MemoryFileUploadHandlerTemporaryFileUploadHandler 共同提供了 Django 的預設檔案上傳行為,即將小型檔案讀入記憶體,將大型檔案讀到磁碟。它們位於 django.core.files.uploadhandler 中。

class MemoryFileUploadHandler[原始碼]

將上傳串流到記憶體中的檔案上傳處理器(用於小型檔案)。

class TemporaryFileUploadHandler[原始碼]

使用 TemporaryUploadedFile 將資料串流到臨時檔案的檔案上傳處理器。

編寫自訂上傳處理器

class FileUploadHandler[原始碼]

所有檔案上傳處理器都應該是 django.core.files.uploadhandler.FileUploadHandler 的子類別。您可以在任何您希望的地方定義上傳處理器。

必要方法

自訂檔案上傳處理器必須定義以下方法:

FileUploadHandler.receive_data_chunk(raw_data, start)[原始碼]

接收檔案上傳的「資料塊」。

raw_data 是一個包含上傳資料的位元組字串。

start 是此 raw_data 資料塊在檔案中的起始位置。

您回傳的資料將會被傳遞到後續上傳處理器的 receive_data_chunk 方法中。透過這種方式,一個處理器可以作為其他處理器的「篩選器」。

receive_data_chunk 回傳 None 可以阻止後續上傳處理器處理此資料塊。如果您要自行儲存上傳的資料,並且不希望後續的處理器儲存資料的副本,這會很有用。

如果您引發 StopUploadSkipFile 例外,則上傳將會中止或該檔案將會被完全略過。

FileUploadHandler.file_complete(file_size)[原始碼]

當檔案完成上傳時呼叫。

處理器應該回傳一個 UploadedFile 物件,該物件將會儲存在 request.FILES 中。處理器也可以回傳 None,表示 UploadedFile 物件應來自後續的上傳處理器。

選用方法

自訂上傳處理器也可以定義以下任何選用方法或屬性

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.upload_complete()[原始碼]

發出信號表示整個上傳(所有檔案)已完成的回呼函數。

FileUploadHandler.upload_interrupted()[原始碼]

發出信號表示上傳被中斷的回呼函數,例如當使用者在檔案上傳期間關閉瀏覽器時。

FileUploadHandler.handle_raw_input(input_data, META, content_length, boundary, encoding)[原始碼]

允許處理器完全覆寫原始 HTTP 輸入的解析。

input_data 是一個支援 read() 的類檔案物件。

METArequest.META 是相同的物件。

content_lengthinput_data 中資料的長度。不要從 input_data 讀取超過 content_length 位元組的資料。

boundary 是此請求的 MIME 分界符。

encoding 是請求的編碼。

如果您希望上傳處理繼續,則回傳 None;如果您希望直接回傳適合請求的新資料結構,則回傳 (POST, FILES) 的元組。

回到頂端