如何撰寫自訂儲存類別¶
如果您需要提供自訂的檔案儲存方式(常見的例子是將檔案儲存在某些遠端系統上),您可以透過定義自訂的儲存類別來實現。您需要遵循以下步驟:
您的自訂儲存系統必須是
django.core.files.storage.Storage
的子類別from django.core.files.storage import Storage class MyStorage(Storage): ...
Django 必須能夠在沒有任何引數的情況下實例化您的儲存系統。這表示任何設定都應該從
django.conf.settings
中取得。from django.conf import settings from django.core.files.storage import Storage class MyStorage(Storage): def __init__(self, option=None): if not option: option = settings.CUSTOM_STORAGE_OPTIONS ...
您的儲存類別必須實作
_open()
和_save()
方法,以及任何其他適用於您的儲存類別的方法。請參閱下方有關這些方法的詳細資訊。此外,如果您的類別提供本機檔案儲存,則必須覆寫
path()
方法。您的儲存類別必須是 可解構的,以便在遷移中用於欄位時可以序列化。只要您的欄位具有本身是 可序列化 的引數,您就可以使用
django.utils.deconstruct.deconstructible
類別裝飾器來實現此目的(這也是 Django 在 FileSystemStorage 上使用的方式)。
預設情況下,以下方法會引發 NotImplementedError
,並且通常必須覆寫
但請注意,並非所有這些方法都是必要的,並且可能會故意省略。事實上,有可能不實作每個方法,仍然擁有一個可以運作的 Storage。
例如,如果列出某些儲存後端的内容變得非常耗費資源,您可能會決定不實作 Storage.listdir()
。
另一個例子是只處理寫入檔案的後端。在這種情況下,您不需要實作上述任何方法。
最終,要實作哪些方法由您決定。不實作某些方法將導致部分(可能損壞的)介面。
您通常也會想要使用專為自訂儲存物件設計的掛鉤。這些是:
- _open(name, mode='rb')¶
必要.
此方法由 Storage.open()
呼叫,是儲存類別用來開啟檔案的實際機制。此方法必須傳回 File
物件,儘管在大多數情況下,您會希望在這裡傳回一些子類別,該子類別會實作特定於後端儲存系統的邏輯。當檔案不存在時,應引發 FileNotFoundError
例外狀況。
- _save(name, content)¶
由 Storage.save()
呼叫。name
已通過 get_valid_name()
和 get_available_name()
,並且 content
本身將是一個 File
物件。
應該傳回已儲存檔案的實際名稱(通常是傳入的 name
,但如果儲存需要變更檔案名稱,則改為傳回新名稱)。
- get_valid_name(name)¶
傳回適用於基礎儲存系統的檔案名稱。傳遞給此方法的 name
引數是要傳送到伺服器的原始檔案名稱,或者,如果 upload_to
是可呼叫的,則是該方法在移除任何路徑資訊後傳回的檔案名稱。覆寫此方法以自訂如何將非標準字元轉換為安全檔案名稱。
Storage
上提供的程式碼僅保留原始檔案名稱中的字母數字字元、句點和底線,並移除其他所有內容。
- get_alternative_name(file_root, file_ext)¶
根據 file_root
和 file_ext
參數傳回替代檔案名稱。預設情況下,會在副檔名之前將底線加上隨機的 7 個字元字母數字字串附加到檔案名稱。
- get_available_name(name, max_length=None)¶
傳回儲存機制中可用的檔案名稱,可能會考慮提供的檔案名稱。傳遞給此方法的 name
引數將已根據上述 get_valid_name()
方法清理為對儲存系統有效的檔案名稱。
如果提供,檔案名稱的長度不會超過 max_length
。如果找不到免費的唯一檔案名稱,則會引發 SuspiciousFileOperation
例外狀況。
如果已存在具有 name
的檔案,則會呼叫 get_alternative_name()
以取得替代名稱。
使用您的自訂儲存引擎¶
將您的自訂儲存與 Django 搭配使用的第一步是告訴 Django 您將使用的檔案儲存後端。這是使用 STORAGES
設定完成的。此設定會將儲存別名(這是一種在整個 Django 中引用特定儲存的方式)對應到該特定儲存後端的設定字典。內部字典中的設定在 STORAGES
文件中有完整的說明。
然後,可以從 django.core.files.storage.storages
字典中透過別名存取儲存。
from django.core.files.storage import storages
example_storage = storages["example"]