Как сделать ссылку на скачивание файла django

Обновлено: 03.07.2024

Для работы с изображениями и другими файлами во фреймворке Python Django существует готовый механизм реализуемый через модели. Процесс хранения картинок и файлов в базах данных может вызвать путаницу если вы не имели особого опыта работы с ними. Процесс создания возможности загрузки файлов состоит из нескольких шагов, которые мы рассмотрим ниже на примерах.

Навигация по посту

Подготовка тестового проекта

Добавление приложения Django в INSTALLED_APPS

Выполнение migrate в Django

Создание модели для загрузки файлов

Каждая модель отображает какую-то таблицу в базе данных. В этих таблицах, а именно колонках, хранятся определенные типы данных (строки, числа и т.д.). Один из таких типов данных - файлы. Однако хранить файлы в SQL базах, в большинстве случаев, считается плохой практикой. Одна из причин не делать этого заключается в непригодности SQL баз в поиске по таким типам данных.

В большинстве случаев хранение файлов организуется в несколько шагов:

Для такой реализации в Django есть два типа полей (Fields):

  • FileField - для любых типов данных;
  • ImageField - наследует все методы FileField, добавляет валидацию картинок и методы. Например мы можем получить размер картинки используя image.width или image.height.

Создание модели с ImageField и FileField в Django

В ImageField добавлена проверка, что файл имеет тип изображения. Так же у ImageField есть методы возвращающие высоту и ширину. Ширину и высоту так же можно сохранить в отдельные модели используя параметры height_field и width_field. Часть этих возможностей по работе с изображениями выполняется через библиотеку Pillow и поэтому ее нужно установить:

Удаление любого объекта удаляет только запись из базы. На файловой системе файл остается.

После создания моделей выполните миграции:

Динамический upload_to

Папки для сохранения данных можно организовать динамически. Например мы можем сделать так, что бы файл сохранялся в каталог с названием сегодняшней даты формата год-месяц-день:

Этот способ соответствует методу strftime() из библиотеки datetime.

Так же можно создать путь соответствующий пользователю, который выполняет загрузку:

Папка соответствующая пользователю будет создана только в том случае, если модель MyModel будет иметь поле с названием user. Т.е. instance - это и есть сам объект модели. Пример того как это можно сделать:

Сохранение картинки в папку пользователя Djagno

Использование существующих файлов и папок с FilePathField

Во фреймворке Python Django есть так же поле FilePathField. Его основная задача - создание записи в базе на основании существующего файла.

При определении такого поля Django сканирует указанный путь получая файлы из него и предлагает вам выбор. После выбора файла - путь до него сохраняется в базе:

Доступны поля для рекурсивного поиска и по маске. Path - это абсолютный путь (в отличие от предыдущих примеров).

В панели администрирования, если указанная папка не пуста, файл будет выводиться следующим образом:

Выбор существующего файла с FilePathField Django

FilePathField не следует использовать в директориях с вашим приложением т.к. приводит к уязвимостям.

Используем CRUD запросы в Django 3 на примере приложения

Переменная MEDIA_ROOT и MEDIA_URL

Для Django до 3-ей версии это выглядело так:

Определение MEDIA_ROOT и MEDIA_URL в Django

Теперь, например, сохранять файлы вы будете по следующему пути:

А открывать их будет по следующей ссылке:

В Django так же есть похожая переменная - STATIC_ROOT и STATIC_URL. Эти переменные указывают на папки в которые вы сами загружали файлы не используя Django. Хоть вы можете соединить STATIC_ROOT и MEDIA_ROOT - это не рекомендуется делать т.к. приведет к уязвимости. Совмещения этих путей стоит избегать.

Панель администрирования

Создание панели администрирования в Django

После этого создайте супер пользователя и запустите сервер:

Создание пользователя администратора в Django

Загрузка файлов и картинок в панели администрирования Django

Если открыть директорию прописанную в "MEDIA_ROOT" можно увидеть загруженные файлы (могут отличаться из-за настроек):

Папка с сохранёнными файлами в Django

Загрузка и вывод файлов

Что бы вывести изображение на странице нужно выполнить следующие шаги:

  1. Создать url связывающий запрос пользователя с какой-то логикой;
  2. Шаблон HTML, который преобразует данные и вернет их пользователю;
  3. Создать функцию или класс, который свяжет url и шаблон.

Реализуем эти пункты

Создание ссылки в urls.py

В вебе есть понятие статических файлов - это любой файл который не изменяясь возвращается пользователю: картинки, видео, файлы css, js и т.д. По умолчанию Django не занимается обработкой таких файлов. Обычно, запросы к статическим файлам обрабатывает другая программа, например веб сервер Nginx.

Включение поддержки загруженных файлов с DEBUG в Django

Вывод изображения на странице

В созданной модели у меня есть 3 поля:

  • title - строка;
  • cover - картинка;
  • book - файл.

Что бы вывести их на странице я создам следующий шаблон по пути:

Создание шаблона и вывод файла на странице в Django

После запуска сервера можно будет увидеть следующий результат (при наличии данных в базе):

Вывод файла и картинки в Django

Загрузка документа со страницы и его сохранение

Что бы сохранить файл с Django мы должны использовать следующую функцию:

Загрузка файла в Django используя request.FILES

Теперь, запустив сервер и, открыв главную страницу, у нас будет возможность загрузки файла в корень MEDIA_ROOT:

В примере выше файл в базу не сохраняется. Что бы путь до файла сохранился в базу мы должны передать ему объект file. Ниже пример, если бы вы загружали несколько файлов сразу:

Создание формы

Все шаги, описанные выше, можно сократить использовав существующие возможности Django. Например в Django есть формы, которые можно создать на основе существующей модели. Такие формы упрощают процесс валидации (соответствует ли тип данных Django типу в базе), представления в шаблоне (HTML теги создаются сами) и много другое.

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

Создание формы ModelForm Django

Вывод формы для загрузки файлов с CreateView в Django

В файл маршрутизации добавим маршрут, который свяжет url с новым классом:

Читайте также: