# Django 4.1.8.dev20230308103347 ドキュメント

# How to write a custom storage class

たとえばリモートシステム上にファイルを保存する場合、カスタムストレージクラスを定義することで、カスタムファイルストレージを作成することが可能です。使用するには以下の手順に従ってください。

1. カスタムストレージシステムは `django.core.files.storage.Storage` のサブクラスでなければなりません。:

       from django.core.files.storage import Storage

       class MyStorage(Storage):
           ...

2. Djangoは引数なしでストレージシステムをインスタンス化できなければなりません。これは、 `` 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. あなたのストレージクラスは `_open()` と `_save()` メソッドと、あなたのストレージクラスに適した他のメソッドを実装しなければなりません。これらのメソッドの詳細については以下を参照してください。

   加えて、あなたのクラスがローカルファイルストレージを提供する場合、 `path()` メソッドをオーバーライドする必要があります。

4. ストレージクラスは deconstructible でなければならないので、マイグレーションのフィールドで使われたときにそれはシリアライズすることができます。フィールドがそれ自身 serializable である引数を持つ限り、これのために `django.utils.deconstruct.deconstructible` クラスデコレータを使うことができます (それが FileSystemStorage で Django が使うものです)。

デフォルトにおいて、以下に示すメソッドは NotImplementedError を発生させます。したがって一般的にオーバーライドする必要があります。

- `Storage.delete()`
- `Storage.exists()`
- `Storage.listdir()`
- `Storage.size()`
- `Storage.url()`

ただし上のメソッドはすべてが必要というわけでもないため、意図的に省略することもできます。もし例外が発生してもそのメソッドを未実装のままにしておくことも可能であり、それでもストレージを動作させることはできます。

特定のストレージバックエンドにおける内容一覧の取得には相当な手間がかかる、ということがわかったとします。その場合は Storage.listdir() の実装をしなくても構いません。

バックエンドとして、単にファイル出力だけを扱うものであったとします。この場合は、上のメソッドをすべて実装する必要がありません。

結局、上のメソッドを実装するかどうかは開発者次第です。メソッドのどれかを未実装のままにしておくというのは、一部分のみの (場合によっては壊れたままの) インターフェースとするということです。

カスタムストレージオブジェクトに固有のフックメソッドを用意することもあるでしょう。以下があります。

`_open`(name, mode='rb')

必須

`Storage.open()` から呼び出されます。このストレージクラスにとって、ファイルを開くために実際に用いられる機能となります。バックエンドストレージシステムに固有のロジックを実装して、特定サブクラスのオブジェクトを戻り値としたい場合も多くありますが、このメソッドは必ず `File` オブジェクトを戻り値としなければなりません。

`_save`(name, content)

`Storage.save()` から呼び出されます。`name` は `get_valid_name()` や `get_available_name()` を通じて得られたものであり、`content` は `File` オブジェクトそのものです。

戻り値は、実際に保存されたファイルの名前です。(通常は処理された `name` ですが、ストレージがファイル名を変更する必要がある場合には、新たな名前を返す必要があります。)

`get_valid_name`(name)

対象としているストレージシステムにて用いることが適切なファイル名を返します。このメソッドに受け渡される `name` 引数は以下のいずれかです。1つはサーバーに送られる元々のファイル名です。もう1つは `upload_to` メソッドが呼び出し可能な場合に、そのメソッドによりパスに関する情報を取り除いた後のファイル名です。ファイル名の中にある非標準の文字を安全なものに変換するようなカスタマイズが必要であれば、このメソッドをオーバーライドします。

`Storage` において実装されているコードにおいては、元々のファイル名の中から、アルファベット、数字、ピリオド、アンダースコアのみが保持され、それ以外は取り除かれます。

`get_alternative_name`(file_root, file_ext)

"file_root"と"file_ext"のパラメーターを基に新たなファイルネームを返します。デフォルトでは、ファイルネームの拡張子の前にアンダーバーとランダムな7文字の英数字の文字列を加えます。

`get_available_name`(name, max_length=None)

ストレージシステムにおいて利用可能なファイル名を返します。これは指定されたファイル名をできるかぎり考慮に入れた名称です。本メソッドに受け渡される `name` 引数は、上に示した `get_valid_name()` メソッドを用いて、ストレージシステムが扱うファイル名として正常化されたものにします。

`max_length` を指定した場合、ファイル名の長さはそれを越えないようにします。適切に一致するファイル名が見つからなかった場合は、例外 `SuspiciousFileOperation` が発生します。

``name``というファイルが既に存在する場合、``get_alternative`_name()`が代わりの名前を得るために呼び出されます。