Spec-Zone.ru › Django 3.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')

Любой экземпляр 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

Примечание

Хотя атрибуты не относящиеся к изображениям, такие как height, width, и size, доступны для экземпляра ImageField, данные изображения в исходном формате нельзя использовать без повторного открытия изображения. Например:

<
>>> 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.

Использование вызываемого объекта

Новое в Django 3.1.

Вы можете использовать вызываемый объект в качестве параметра 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/3.2/topics/files/

Spec-Zone.ru

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