Управление файлами
Этот документ описывает API доступа к файлам Django для файлов, таких как загруженные пользователем. API низкого уровня достаточно универсальны, чтобы вы могли использовать их для других целей. Если вы хотите обрабатывать «статические файлы» (JS, CSS и т. д.), см. Как управлять статическими файлами (например, изображениями, JavaScript, CSS).
По умолчанию Django хранит файлы локально, используя настройки MEDIA_ROOT и 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")
specs = models.FileField(upload_to="specs")
Любой 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 'https://media.example.com/cars/chevy.jpg'
Этот объект — car.photo в примере — это объект File, что означает, что он имеет все методы и атрибуты, описанные ниже.
Примечание
Файл сохраняется при сохранении модели в базе данных, поэтому фактическое имя файла, используемое на диске, нельзя гарантировать, пока модель не будет сохранена.
Например, вы можете изменить имя файла, установив атрибут name файла на путь, относительный к расположению системы хранения файлов (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
Чтобы сохранить существующий файл на диске в FileField:
>>> from pathlib import Path
>>> from django.core.files import File
>>> path = Path("/some/external/specs.pdf")
>>> car = Car.objects.get(name="57 Chevy")
>>> with path.open(mode="rb") as f:
... car.specs = File(f, name=path.name)
... car.save()
...
Примечание
Несмотря на то, что атрибуты ImageField не относящиеся к изображениям, такие как height, width, и size, доступны на экземпляре, данные изображения в underlying не могут быть использованы без повторного открытия изображения. Например:
>>> 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 всякий раз, когда необходимо представить файл.
Большую часть времени вы будете использовать File предоставленный Django (например, файл, прикрепленный к модели, как показано выше, или загруженный файл).
Если вам нужно создать 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 использует систему хранения файлов 'django.core.files.storage.FileSystemStorage'. Если вы явно не укажете систему хранения в ключе default настройки STORAGES, будет использоваться именно она.
Подробности встроенной системы хранения файлов см. ниже, а информацию о написании собственной системы хранения файлов см. в разделе Как написать класс пользовательской системы хранения.
Объекты хранения
Хотя большую часть времени вы захотите использовать объект 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, который реализует базовые функции хранения файлов в локальной файловой системе.
Например, следующий код будет хранить загруженные файлы в /media/photos независимо от значения настройки MEDIA_ROOT:
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.
Использование вызова функции
Вы можете использовать вызов функции в качестве параметра storage для FileField или ImageField. Это позволяет изменять используемую систему хранения во время выполнения, выбирая разные хранилища для разных сред, например.
Ваш вызов функции будет оценен при загрузке классов моделей и должен возвращать экземпляр 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)
Чтобы установить хранилище, определенное в настройке STORAGES, можно использовать storages:
from django.core.files.storage import storages
def select_storage():
return storages["mystorage"]
class MyModel(models.Model):
upload = models.FileField(storage=select_storage)
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/5.1/topics/files/