# Τεκμηρίωση του Django - 5.2.8

# How to write a custom storage class

Αν θέλετε να έχετε το δικό σας σύστημα αποθήκευσης αρχείων – ένα συνηθισμένο παράδειγμα είναι η αποθήκευση αρχείων σε ένα απομακρυσμένο σύστημα – μπορείτε να το κάνετε ορίζοντας μια δικιά σας κλάση αποθήκευσης (storage class). Θα χρειαστεί να ακολουθήσετε τα παρακάτω βήματα:

1. Το δικό σας σύστημα αποθήκευσης θα πρέπει να είναι μια subclass της κλάσης `django.core.files.storage.Storage`:

       from django.core.files.storage import Storage

       class MyStorage(Storage): ...

2. Το Django πρέπει να είναι σε θέση να αρχικοποιεί το δικό σας σύστημα αποθήκευσης χωρίς arguments. Αυτό σημαίνει ότι τυχόν ρυθμίσεις του δικού σας συστήματος θα πρέπει να λαμβάνονται από το γενικό αρχείο ρυθμίσεων `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.

   Επιπροσθέτως, αν η κλάση σας παρέχει τη δυνατότητα τοπικής αποθήκευσης των αρχείων, θα πρέπει να παρακάμπτει (override) τη μέθοδο `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:

- `Storage.delete()`

- `Storage.exists()`

- `Storage.listdir()`

- `Storage.size()`

- `Storage.url()`

Υπόψιν ότι δεν είναι απαραίτητο, όλες αυτές οι μέθοδοι, να υλοποιηθούν και μερικές μπορούν σκοπίμως να παραλειφθούν. Παραβλέποντας, λοιπόν, μερικές από αυτές το σύστημα αποθήκευσης σας θα μπορεί να λειτουργεί.

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()`.

Άλλο παράδειγμα είναι ένα άλλο σύστημα αποθήκευσης που μοναδικός του ρόλος είναι η εγγραφή σε αρχεία. Σε αυτή την περίπτωση δεν χρειάζεται να υλοποιήσετε καμία από τις παραπάνω μεθόδους.

Με άλλα λόγια, το ποιες μέθοδοι θα υλοποιηθούν εξαρτάται από σας και τις ανάγκες σας. Από την άλλη, αν μερικές δεν υλοποιηθούν θα καταλήξετε με ένα λειψό (πιθανόν χαλασμένο) interface.

Επίσης, ίσως να θέλατε να χρησιμοποιήσετε κάποια hooks τα οποία έχουν σχεδιαστεί για παραμετροποιήσιμα συστήματα αποθήκευσης. Αυτά είναι:

_open(name, mode='rb')

Υποχρεωτικό

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)

Η μέθοδος αυτή καλείται από την `Storage.save()`. Το όρισμα `name` θα έχει περάσει ήδη από την μέθοδο `get_valid_name()` και `get_available_name()` και το όρισμα `content` θα είναι ένα `File` object.

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)

Επιστρέφει το όνομα του αρχείου το οποίο θεωρείται έγκυρο για να αποθηκευτεί στη συνέχεια από το σύστημα αποθήκευσης. Το όρισμα `name` είναι είτε το αρχικό όνομα του αρχείου που στάλθηκε στον server είτε, αν το `upload_to` είναι κάποιο callable, το όνομα που επεστράφη από αυτή τη μέθοδο αφού έχει αφαιρεθεί κάθε πληροφορία σχετικά με το path του αρχείου. Μπορείτε να παρακάμψετε αυτή τη μέθοδο για να ελέγξετε το πως οι μη-τυποποιημένοι χαρακτήρες μπορούν να μετατραπούν σε έγκυρα-ασφαλή ονόματα αρχείων.

Ο κώδικας του `Storage` διατηρεί μόνο τους αλφαριθμητικούς χαρακτήρες, τις τελείες και τις κάτω παύλες από τα αρχικά ονόματα των αρχείων (αυτά που επιλέγονται προς αποθήκευση), αφαιρώντας οποιονδήποτε άλλον χαρακτήρα.

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)

Επιστρέφει ένα όνομα αρχείου το οποίο είναι διαθέσιμο στο μηχανισμό αποθήκευσης και πιθανόν να λαμβάνει υπόψιν του το, περασμένο ως όρισμα, όνομα του αρχείου. Το όρισμα `name` θα έχει ήδη μετατραπεί σε κάποιο έγκυρο όνομα αρχείου για αποθήκευση σύμφωνα με την μέθοδο `get_valid_name()` που περιγράφηκε πιο πάνω.

Το μήκος του ονόματος του αρχείου δεν μπορεί να υπερβαίνει το `max_length`, αν αυτό δίνεται. Αν ένα μοναδικό όνομα αρχείου δεν μπορεί να βρεθεί, τότε γίνεται raise το exception `SuspiciousFileOperation`.

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"]