Pisanie niestandardowego systemu pamięci

Jeśli potrzebujesz dostarczyć niestandardowy magazyn plików - popularnym przykładem jest przechowywanie plików na zdalnym systemie – możesz zrobić to definiując niestandardową klasę magazynu. Będziesz potrzebował wykonać następujące kroki:

  1. Twój niestandardow magazyn musi być podklasą django.core.files.storage.Storage:

    from django.core.files.storage import Storage
    
    class MyStorage(Storage):
        ...
    
  2. Django musi być w stanie stworzyć instancje twojego magazynu bez żadnych argumentów. To znaczy bez jakiegokolwiek ustawienia z 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
            ...
    
  3. Twój magazyn musi implementować metody _open() i _save() wraz z innymi metodami odpowiednimi dla twojej klasy przechowywania. Zobacz poniżej, aby dowiedzieć się więcej o tych metodach.

    W dodatki, jeśli twoja klasa dostarcza lokalny magazyn plików musi przeciążać metodę path().

  4. Your storage class must be deconstructible so it can be serialized when it’s used on a field in a migration. As long as your field has arguments that are themselves serializable, you can use the django.utils.deconstruct.deconstructible class decorator for this (that’s what Django uses on FileSystemStorage).

By default, the following methods raise NotImplementedError and will typically have to be overridden:

Należy jednak pamiętać, że nie wszystkie te metody są wymagane i można je celowo pominąć. Tak się składa, że ​​możliwe jest pozostawienie każdej metody niezatwierdzonej i nadal działającej pamięci masowej.

By way of example, if listing the contents of certain storage backends turns out to be expensive, you might decide not to implement Storage.listdir().

Kolejnym przykładem może być backend, który jedynie obsługi zapisywanie do pliku. W tym przypadku, mógłbyś nie potrzebować implementować żadnej z powyższych metod.

Ostatecznie, które z tych metod są zaimplementowane zależy od Ciebie. Pozostawienie niektórych metod niezaimplementowanych może w rezultacie stworzyć częściowo (prawdopodobnie zepsuty) interfejs

Dodatkowo zazwyczaj będziesz chciał używać uchwytów zaprojektowanych specjalnie do trzymania niestandardowych obiektów pamięci. To są:

_open(name, mode='rb')

Wymagany.

Wywoływany przez Storage.open(), jest to aktualny mechanizm używany przez klasę do otwierania pliku. Musi on zwracać obiekt File, choć w wielu przypadkach, będziesz chciał zwrócić jakąś podklasę implementującą specyficzną logikę dla systemu pamięci

_save(name, content)

Called by Storage.save(). The name will already have gone through get_valid_name() and get_available_name(), and the content will be a File object itself.

Powinien zwrócić aktualną nazwę pliku, który został zapisany(zazwyczaj name jest przekazany, ale jeśli pamięć potrzebuje zmienić nazwę pliku zwróć nową nazwę).

get_valid_name(name)

Returns a filename suitable for use with the underlying storage system. The name argument passed to this method is either the original filename sent to the server or, if upload_to is a callable, the filename returned by that method after any path information is removed. Override this to customize how non-standard characters are converted to safe filenames.

The code provided on Storage retains only alpha-numeric characters, periods and underscores from the original filename, removing everything else.

get_alternative_name(file_root, file_ext)

Returns an alternative filename based on the file_root and file_ext parameters. By default, an underscore plus a random 7 character alphanumeric string is appended to the filename before the extension.

get_available_name(name, max_length=None)

Returns a filename that is available in the storage mechanism, possibly taking the provided filename into account. The name argument passed to this method will have already cleaned to a filename valid for the storage system, according to the get_valid_name() method described above.

The length of the filename will not exceed max_length, if provided. If a free unique filename cannot be found, a SuspiciousFileOperation exception is raised.

If a file with name already exists, get_alternative_name() is called to obtain an alternative name.