Django: загрузка FileField и ImageField из файловой системы

Не знаю как вы, а я чаще стал сталкиваться с ситуацией, когда мне нужно программно загрузить файл из локальной файловой системы или с помощью удаленного URL в модель Django. Это может понадобиться в контексте работы в оболочке Python, исполнения отдельного скрипта или команды управления Django.

В типичном веб-приложении такая задача встречается нечасто. Я заметил, что мы это делаем, когда переносим сайт с какой-то другой технологии на Django, и привязываем изображение к некой контентной сущности.

Если вы поищете ответ как сделать это в Google, то обнаружите документацию Django File Uploads, File objects и Managing Files, которые сами по себе отличные. Тем не менее они не содержат последовательного руководства для решения нашей задачи.

Первый порыв — присвоить полю модели путь к файлу, но это ведет к потере информации об относительном пути к файлу, в которой нуждается Django.

Читайте также  Как узнать свою операционную систему Windows

Я выделил время, чтобы написать этот пост в основном для собственного блага, чтобы не искать заново решение в будущем. Но, надеюсь, вы также получите некоторую пользу.

Этапы загрузки локального файла в Django ImageField

Действия, которые необходимо выполнить:

  1. Получить файл (если он удаленный) и сохранить его локально
  2. Открыть файл как обычный объект файла Python
  3. Конвертировать открытый файл в Django FIle
  4. Привязать его к полю вашей модели

Пример модели

Предположим, у нас есть модель вроде этой:

from django.db import models

class Company(models.Model):
    name = models.CharField(max_length=100) 
    logo = models.ImageField()

Давайте создадим запись для RevSys, скачав логотип с помощью библиотеки requests:

import requests
from django.core.files import File

from .models import Company

r = requests.get(“http://media.revsys.com/img/revsys-logo.png”)

with open(“/tmp/revsys-logo.png”, “wb”) as f:
    f.write(r.content)

reopen = open(“/tmp/revsys-logo.png”, “rb”)
django_file = File(reopen)

revsys = Company()
revsys.name = “Revolution Systems”
revsys.logo.save(“revsys-logo.png”, django_file, save=True)

Последняя строка здесь самая важная. Методу save передается три аргумента:

  1. Относительный путь и имя файла внутри MEDIA_ROOT.
  2. Файл, открытый с помощью File объекта Django.
  3. Логическое значение, показывающее хотим ли мы сохранить экземпляр revsys модели Company после того, как изображение сохранено.
Читайте также  Скриншот изображения без дополнений

Иногда, если вы работаете с набором изображений, вам требуется распарсить URL или пути к файлам для извлечения имен файлов. Нижеследующий код послужит отправной точкой. Обратите внимание, что тут используется Python 3:

import os 
from urllib.parse import urlparse

# from urlparse import urlparse for Python 2.7

url = “http://media.revsys.com/img/revsys-logo.png” 
filename = os.path.basename(urlparse(url).path)

# This returns ‘revsys-logo.png’ from the URL

…

revsys.logo.save(filename, django_file, save=True)`

Надеюсь, это вам поможет!

Эта статья перевод. Оригинал: Loading Django FileField and ImageFields from the file system

Ссылка на основную публикацию