# Django 5.2.9 - dokumentacja

# Jak napisać klasę niestandardowego magazynu plików

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 niestandardowy 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. Your storage class must implement the `_open()` and `_save()` methods, along with any other methods appropriate to your storage class. See below for more on these methods.

   Dodatkowo, 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).

Domyślnie, następujące metody wywołują `NotImplementedError` i zazwyczaj muszą być nadpisane:

- `Storage.delete()`

- `Storage.exists()`

- `Storage.listdir()`

- `Storage.size()`

- `Storage.url()`

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.

Na przykład, jeśli zawartość listy pamięci backendu okazuje się być zbyt kosztowna, możesz zdecydować się nie implementować `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.

Called by `Storage.open()`, this is the actual mechanism the storage class uses to open the file. This must return a `File` object, though in most cases, you’ll want to return some subclass here that implements logic specific to the backend storage system. The `FileNotFoundError` exception should be raised when a file doesn’t exist.

_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.

Should return the actual name of the file saved (usually the `name` passed in, but if the storage needs to change the file name return the new name instead).

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.

Kod podany na `Storage` zachowuje tylko znaki alfa-numeryczne, kropki i podkreślenia z oryginalnej nazwy pliku, usuwając wszystko inne.

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.

## Use your custom storage engine

The first step to using your custom storage with Django is to tell Django about the file storage backend you’ll be using. This is done using the `STORAGES` setting. This setting maps storage aliases, which are a way to refer to a specific storage throughout Django, to a dictionary of settings for that specific storage backend. The settings in the inner dictionaries are described fully in the `STORAGES` documentation.

Storages are then accessed by alias from the `django.core.files.storage.storages` dictionary:

    from django.core.files.storage import storages

    example_storage = storages["example"]