Så här skriver du en anpassad lagringsklass¶
Om du behöver tillhandahålla anpassad fillagring - ett vanligt exempel är lagring av filer på ett fjärrsystem - kan du göra det genom att definiera en anpassad lagringsklass. Du måste följa dessa steg:
Ditt anpassade lagringssystem måste vara en underklass av
django.core.files.storage.Storage:from django.core.files.storage import Storage class MyStorage(Storage): ...
Django måste kunna instansiera ditt lagringssystem utan några argument. Detta innebär att alla inställningar ska hämtas från
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 ...
Din lagringsklass måste implementera metoderna
_open()och_save(), tillsammans med andra metoder som är lämpliga för din lagringsklass. Se nedan för mer information om dessa metoder.Om din klass tillhandahåller lokal fillagring måste den dessutom åsidosätta metoden
path().Din lagringsklass måste vara deconstructible så att den kan serialiseras när den används på ett fält i en migrering. Så länge ditt fält har argument som själva är serializable, kan du använda
django.utils.deconstruct.deconstructibleklassdekorator för detta (det är vad Django använder på FileSystemStorage).
Som standard ger följande metoder upphov till NotImplementedError och måste normalt åsidosättas:
Observera dock att alla dessa metoder inte är obligatoriska och att de kan utelämnas avsiktligt. I själva verket är det möjligt att lämna varje metod oimplementerad och ändå ha en fungerande lagring.
Som exempel kan nämnas att om det visar sig vara dyrt att lista innehållet i vissa lagringsbackends kan du välja att inte implementera Storage.listdir().
Ett annat exempel skulle vara en backend som bara hanterar skrivning till filer. I det här fallet behöver du inte implementera någon av ovanstående metoder.
I slutändan är det upp till dig att bestämma vilka av dessa metoder som ska implementeras. Om du lämnar vissa metoder oimplementerade resulterar det i ett partiellt (eventuellt trasigt) gränssnitt.
Du vill också vanligtvis använda hooks som är särskilt utformade för anpassade förvaringsobjekt. Dessa är:
- _open(name, mode='rb')¶
Krävs.
Anropas av Storage.open(), detta är den faktiska mekanism som lagringsklassen använder för att öppna filen. Detta måste returnera ett File-objekt, men i de flesta fall vill du returnera någon underklass här som implementerar logik som är specifik för backend-lagringssystemet. Undantaget FileNotFoundError bör utlösas när en fil inte finns.
- _save(name, content)¶
Anropas av Storage.save(). name kommer redan att ha gått igenom get_valid_name() och get_available_name(), och content kommer att vara ett File-objekt självt.
Ska returnera det faktiska namnet på den sparade filen (vanligtvis det namn som skickas in, men om lagringen behöver ändra filnamnet returneras det nya namnet istället).
- get_valid_name(name)¶
Returnerar ett filnamn som är lämpligt för användning med det underliggande lagringssystemet. Argumentet name som skickas till den här metoden är antingen det ursprungliga filnamnet som skickas till servern eller, om upload_to är en anropsbar, det filnamn som returneras av den metoden efter att all sökvägsinformation har tagits bort. Åsidosätt detta för att anpassa hur icke-standardiserade tecken konverteras till säkra filnamn.
Den kod som tillhandahålls på Storage behåller endast alfanumeriska tecken, punkter och understreck från det ursprungliga filnamnet och tar bort allt annat.
- get_alternative_name(file_root, file_ext)¶
Returnerar ett alternativt filnamn baserat på parametrarna file_root och file_ext. Som standard läggs ett understreck plus en slumpmässig alfanumerisk sträng med 7 tecken till filnamnet före tillägget.
- get_available_name(name, max_length=None)¶
Returnerar ett filnamn som är tillgängligt i lagringsmekanismen, eventuellt med hänsyn tagen till det angivna filnamnet. Argumentet name som skickas till den här metoden kommer redan att ha rensats till ett filnamn som är giltigt för lagringssystemet, enligt metoden get_valid_name() som beskrivs ovan.
Längden på filnamnet kommer inte att överstiga max_length, om det anges. Om ett fritt unikt filnamn inte kan hittas, uppstår ett SuspiciousFileOperation undantag.
Om en fil med namn redan finns, anropas get_alternative_name() för att få ett alternativt namn.
Använd din anpassade lagringsmotor¶
Det första steget för att använda din anpassade lagring med Django är att berätta för Django om den fillagringsbackend du kommer att använda. Detta görs med hjälp av inställningen STORAGES. Denna inställning mappar lagringsalias, som är ett sätt att hänvisa till en specifik lagring i hela Django, till en ordbok med inställningar för den specifika lagringsbackend. Inställningarna i de inre ordböckerna beskrivs i sin helhet i STORAGES dokumentation.
Lagren nås sedan via alias från django.core.files.storage.storages ordlistan:
from django.core.files.storage import storages
example_storage = storages["example"]