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.deconstructible
klassdekorator 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 krokar 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"]