Spec-Zone.ru › Django 4.2

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

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

from django.core.files.storage import storages


class MyModel(models.Model):
    upload = models.FileField(storage=lambda: storages["custom_storage"])
Изменено в Django 4.2:

Добавлена поддержка storages.

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

Spec-Zone.ru

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