Файловый браузер для плагина Imagemanager в django-wysiwyg-redactor

Те, кто когда-либо сталкивался с PHP-фреймворком Yii, однозначно знают о существовании замечательного легковесного WYSIWYG-радактора за авторством конторы Imperavi. Так как редактор проприетарный - для Yii его , фреймворка, сообществом была приобретена OEM-лицензия. В настоящее время, вроде как, это визуальный редактор входит в состав дистрибутива Yii.

Касательно Django правомерность использования сего сего продукта мне до конца не ясна. Да и не сильно интересно, честно сказать. Благо существует реализация интеграции Redactor с Django. Автор данной реализации в файле-описании лицензионных заморочек говорит буквально следующее:
Я, douglasmirandasilva@gmail.com, приобрел лицензию  (https://imperavi.com/redactor/license/), которая позволяет мне использовать данное проприетарное программное обеспечение (Redactor II) как часть моей библиотеки для Django. Посему, если вы используете Redactor II как часть django-wysiwyg-redactor, покупать отдельную лицензию для оного вам не нужно.

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

Плагин Image Manager

Для редактора имеется некоторое количество дополнительных плагинов разной степени полезность. Среди них - Image Manager. Плагин, обеспечивающий удобную работу с изображениями в тексте. Больше скажу: если б не он, то я для себя причин использования WYSIWYG не нахожу вообще. WYSIWYG вообще, не конкретно этот.

Среди прочего в Image Manager заложен функционал простого браузера, позволяющего выбирать картинки из каталога на сервере. Не из любого, к сожалению, а из того, где вы находитесь согласно вашим настройкам директорий для Redactor.

Браузер для Image Manager

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

[
    { "thumb": "1m.jpg", "url": "1.jpg", "title": "Image 1", "id": 1  },
    { "thumb": "2m.jpg", "url": "2.jpg", "title": "Image 2", "id": 2  }
]

За этими данными редактор обращается по заданному настройками адресу.  Формирование же списка файлов в каталоге и его отдача в JSON - задача, которую разработчик(и) плагина перекладывают на наши плечи. Ну и фиг с ними, с лодырями. Мы не такие, сделаем. Тем более, что ничего сложного в том нет. Тут лишь один затык - просто понять изначально, что Image Manager от нас этого ожидает. Это не слишком очевидно, скажем так.

Реализация отдачи списка  изображений в JSON

Напишем view, про обращении к которому Image Manager будет получать содержимое нужного каталога в JSON. Где его хранить? У меня для таких общепроектных приблуд, используется файл utils.py, расположенный в том же каталоге, что и settings.py.

Прежде импортируем библиотеки, что нам понадобятся:

# utils.py
import os, json, datetime
from django.conf import settings
from django.http import HttpResponse

Теперь реализуем наш view:

# utils.py
def redactor_imagemanager(request):
    """
    Метод возвращает список изображений из папки загрузки для
    Redactor  в формате JSON (для плагина imagemanager).
    Пример возвращаемых данных:
    [
        {'thumb': 'thumb.jpg', 'image': 'image.jpg', 'title': 'title one'},
        {'thumb': 'thumb2.jpg', 'image': 'image2.jpg', 'title': 'other title'}
    ]
    """
    images = []
    # Определяемся с каталогом, где хранятся картинки.
    upload_to = get_images_upload_path()
    path = os.path.join(settings.MEDIA_ROOT, upload_to)
    if os.path.exists(path):
        # Перебираем файлы, хранящиеся в полученном каталоге,
        # сохраняя подходящие в список.
        alist_filter = ['jpg', 'png', 'gif']
        images = []
        for image in os.listdir(path):
            if image[-3:] in alist_filter:
                image_path = "%s%s%s" % (settings.MEDIA_URL, upload_to, image)
                image_dict = {'thumb': image_path, 'image': image_path}
                images.append(image_dict)
    # Перегоняем наш список с картинками каталога в JSON,
    # и отправляем все это редактору.
    return HttpResponse(json.dumps(images),
                        content_type='application/json') 

В коде выше мы обращаемся к функции get_images_upload_path(). Она у нас возвращает путь, по которому редактор будет сохранять загруженные изображения. Соответственно и браузер Image Manager`а будет нам показывать файлы картинок, что находятся именно по этому пути.

Опишем get_images_upload_path(). Все в том же utils.py:

# utils.py
def get_images_upload_path():
    """
    Получаем путь для загрузки файлов. 
    У меня загруженные изо-я раскладываются по каталогам в соответствии
    с текущим годом и месяцем. Вы же, естественно, вольны реализовать это на свое 
    усмотрение.
    """
    today = datetime.datetime.today()
    return '{0}/{1}/'.format(today.year, today.month) 

Теперь открываем основной urls.py проекта, и дописываем в него путь, по которому Image Maganer будет запрашивать список изображений.

# urls.py
...
from .utils import redactor_imagemanager
   
   
urlpatterns = [
    ... ,
    url(r'^redactor-imagemanager/',
        redactor_imagemanager, name='redactor-imagemanager'),
    ... ,
    ]

Остался последний штрих - соединить в единое работающее целое все, что мы написали выше. Открываем settings.py проекта, и добавляем/правим в нем настройки редактора.

# settings.py
from django.urls import reverse_lazy
from yardaeva.utils import get_images_upload_path
   
REDACTOR_OPTIONS = { 
                    'lang': 'ru',
                    'plugins': ['source', 'imagemanager', 'fullscreen'],
                    # Ради этой строки ниже все наше веселье и затевалось. 
                    'imageManagerJson': reverse_lazy('redactor-imagemanager'),
                    }
REDACTOR_UPLOAD = get_images_upload_path()