ファイルの管理
このドキュメントでは、ユーザーがアップロードしたファイルなどのファイルに対するDjangoのファイルアクセスAPIについて説明します。 下位レベルのAPIは十分に一般的であるため、他の目的に使用できます。 「静的ファイル」(JS、CSSなど)を処理する場合は、を参照してください。 静的ファイルの管理(例: 画像、JavaScript、CSS) 。
デフォルトでは、Djangoは:setting: `MEDIA_ROOT` および:setting:` MEDIA_URL` 設定を使用して、ファイルをローカルに保存します。 以下の例では、これらのデフォルトを使用していることを前提としています。
ただし、Djangoには、カスタムファイルストレージシステムを作成する方法が用意されており、Djangoがファイルを保存する場所と方法を完全にカスタマイズできます。 このドキュメントの後半では、これらのストレージシステムがどのように機能するかについて説明します。
モデルでのファイルの使用
FileField または ImageField を使用する場合、Djangoはそのファイルを処理するために使用できる一連のAPIを提供します。
ImageField を使用して写真を保存する次のモデルについて考えてみます。
from django.db import models
class Car(models.Model):
name = models.CharField(max_length=255)
price = models.DecimalField(max_digits=5, decimal_places=2)
photo = models.ImageField(upload_to='cars')
すべてのCar
インスタンスには、添付の写真の詳細を取得するために使用できるphoto
属性があります。
>>> car = Car.objects.get(name="57 Chevy")
>>> car.photo
<ImageFieldFile: cars/chevy.jpg>
>>> car.photo.name
'cars/chevy.jpg'
>>> car.photo.path
'/media/cars/chevy.jpg'
>>> car.photo.url
'http://media.example.com/cars/chevy.jpg'
このオブジェクト(例ではcar.photo
)はFile
オブジェクトです。つまり、以下で説明するすべてのメソッドと属性があります。
ノート
ファイルはデータベースへのモデルの保存の一部として保存されるため、ディスクで使用される実際のファイル名は、モデルが保存されるまで信頼できません。
たとえば、デフォルトのを使用している場合は、ファイルの name をファイルストレージの場所からの相対パス(:setting: `MEDIA_ROOT` )に設定することで、ファイル名を変更できます。 ] FileSystemStorage ):
>>> import os
>>> from django.conf import settings
>>> initial_path = car.photo.path
>>> car.photo.name = 'cars/chevy_ii.jpg'
>>> new_path = settings.MEDIA_ROOT + car.photo.name
>>> # Move the file on the filesystem
>>> os.rename(initial_path, new_path)
>>> car.save()
>>> car.photo.path
'/media/cars/chevy_ii.jpg'
>>> car.photo.path == new_path
True
ノート
ImageField height
、width
、size
などの非画像データ属性はインスタンスで使用できますが、基になる画像データは使用できません画像を再度開かずに。 例えば:
>>> from PIL import Image
>>> car = Car.objects.get(name='57 Chevy')
>>> car.photo.width
191
>>> car.photo.height
287
>>> image = Image.open(car.photo)
# Raises ValueError: seek of closed file.
>>> car.photo.open()
<ImageFieldFile: cars/chevy.jpg>
>>> image = Image.open(car.photo)
>>> image
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=191x287 at 0x7F99A94E9048>
Fileオブジェクト
内部的には、Djangoはファイルを表す必要があるときはいつでも django.core.files.File インスタンスを使用します。
ほとんどの場合、Djangoから提供されたFile
を使用します(つまり、 上記のようにモデルに添付されたファイル、またはアップロードされたファイル)。
File
を自分で作成する必要がある場合、最も簡単な方法は、Pythonの組み込みfile
オブジェクトを使用して作成することです。
>>> from django.core.files import File
# Create a Python file object using open()
>>> f = open('/path/to/hello.world', 'w')
>>> myfile = File(f)
これで、 File クラスの文書化された属性とメソッドのいずれかを使用できます。
この方法で作成されたファイルは自動的に閉じられないことに注意してください。 次のアプローチを使用して、ファイルを自動的に閉じることができます。
>>> from django.core.files import File
# Create a Python file object using open() and the with statement
>>> with open('/path/to/hello.world', 'w') as f:
... myfile = File(f)
... myfile.write('Hello World')
...
>>> myfile.closed
True
>>> f.closed
True
多数のオブジェクトをループでファイルフィールドにアクセスする場合は、ファイルを閉じることが特に重要です。 ファイルにアクセスした後に手動でファイルを閉じないと、ファイル記述子が不足するリスクが生じる可能性があります。 これにより、次のエラーが発生する可能性があります。
OSError: [Errno 24] Too many open files
ファイルストレージ
舞台裏では、Djangoはファイルを保存する方法と場所に関する決定をファイルストレージシステムに委任します。 これは、ファイルシステム、ファイルのオープンと読み取りなどを実際に理解するオブジェクトです。
Djangoのデフォルトのファイルストレージは、:setting: `DEFAULT_FILE_STORAGE` 設定で指定されます。 ストレージシステムを明示的に提供しない場合は、これが使用されます。
組み込みのデフォルトファイルストレージシステムの詳細については、以下を参照してください。独自のファイルストレージシステムの作成については、カスタムストレージシステムの作成を参照してください。
ストレージオブジェクト
ほとんどの場合、File
オブジェクト(そのファイルの適切なストレージに委任する)を使用する必要がありますが、ファイルストレージシステムを直接使用することもできます。 カスタムファイルストレージクラスのインスタンスを作成できます。または、多くの場合、より便利なグローバルデフォルトストレージシステムを使用できます。
>>> from django.core.files.base import ContentFile
>>> from django.core.files.storage import default_storage
>>> path = default_storage.save('path/to/file', ContentFile(b'new content'))
>>> path
'path/to/file'
>>> default_storage.size(path)
11
>>> default_storage.open(path).read()
b'new content'
>>> default_storage.delete(path)
>>> default_storage.exists(path)
False
ファイルストレージAPIについては、ファイルストレージAPI を参照してください。
組み込みのファイルシステムストレージクラス
Djangoには、基本的なローカルファイルシステムファイルストレージを実装する django.core.files.storage.FileSystemStorage クラスが付属しています。
たとえば、次のコードは、:setting: `MEDIA_ROOT` の設定に関係なく、アップロードされたファイルを/media/photos
の下に保存します。
from django.core.files.storage import FileSystemStorage
from django.db import models
fs = FileSystemStorage(location='/media/photos')
class Car(models.Model):
...
photo = models.ImageField(storage=fs)
カスタムストレージシステムは同じように機能します。storage
引数として FileField に渡すことができます。
呼び出し可能オブジェクトの使用
バージョン3.1の新機能。
FileField または ImageField の storage パラメーターとしてcallableを使用できます。 これにより、実行時に使用済みストレージを変更できます。たとえば、環境ごとに異なるストレージを選択できます。
呼び出し可能オブジェクトは、モデルクラスが読み込まれるときに評価され、 Storage のインスタンスを返す必要があります。
例えば:
from django.conf import settings
from django.db import models
from .storages import MyLocalStorage, MyRemoteStorage
def select_storage():
return MyLocalStorage() if settings.DEBUG else MyRemoteStorage()
class MyModel(models.Model):
my_file = models.FileField(storage=select_storage)