Управление файлами
Этот документ описывает 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 'http://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, доступны для экземпляра, данные изображения в исходном виде нельзя использовать без повторного открытия изображения. Например:
>>> 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)
Добавлена поддержка storages.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/5.0/topics/files/