Управление файлами
В данном документе описываются 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')
Любой Car экземпляр будет иметь атрибут photo, который вы можете использовать для получения подробностей о прикрепленной фотографии:
>>> car = Car.objects.get(name="57 Chevy") >>> car.photo <ImageFieldFile: 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
Объект File
Внутри Django используется экземпляр django.core.files.File всякий раз, когда ему необходимо представить файл.
В большинстве случаев вы просто используете экземпляр File, предоставленный Django (т. е. файл, прикрепленный к модели, как показано выше, или, возможно, загруженный файл).
Если вам необходимо создать объект File самостоятельно, самый простой способ — создать его с помощью объекта file встроенного в Python:
>>> 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
Закрытие файлов особенно важно при обращении к полям файлов в цикле по большому количеству объектов. Если файлы не закрываются вручную после доступа к ним, существует риск исчерпания дескрипторов файлов. Это может привести к следующей ошибке:
IOError: [Errno 24] Too many open files
Система хранения файлов
Внутри Django решения о том, как и где хранить файлы, делегируются системе хранения файлов. Это объект, который на самом деле понимает такие вещи, как файловые системы, открытие и чтение файлов и т. д.
По умолчанию в Django используется система хранения файлов, заданная настройкой 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('new content'))
>>> path
'/path/to/file'
>>> default_storage.size(path)
11
>>> default_storage.open(path).read()
'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.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/2.0/topics/files/