Spec-Zone.ru › Django 4.1

Управление файлами

Этот документ описывает 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 использует систему хранения файлов, заданную настройкой 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, который реализует базовые хранение файлов на локальной файловой системе.

Например, следующий код сохранит загруженные файлы в /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)

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/4.1/topics/files/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API