Создание сайта на Django: Урок 49, чистка медиа-файлов, оптимизация изображений
avatar
7 | (offline)
❤️‍🔥Notehunter Developer
Добавлено:
Категория: Руководства «Django»
Комментариев: 0

Первое, что мы установим, это django-cleanup. Весьма полезная таблетка, которая при удалении статей, или даже generic fk связей удаляет вслед и изображения и прочие медиа файлы.

Приложение django-cleanup автоматически удаляет файлы для FileField, ImageField и подклассов. При изменении значения FileField и сохранении модели старый файл удаляется. При удалении модели с полем FileField файл также удаляется. Файл, заданный как значение по умолчанию для FileField, не будет удален.

Установка django-cleanup

В консоли: pip install django-cleanup

Результат установки:

(venv) PS C:\Users\Razilator\Desktop\Courses\App\backend> pip install django-cleanup
Collecting django-cleanup
  Using cached django_cleanup-6.0.0-py2.py3-none-any.whl (10.0 kB)
Installing collected packages: django-cleanup
Successfully installed django-cleanup-6.0.0

Далее нам необходимо добавить этот модуль в установленные приложения settings.py:

backend/settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sites',
    'django.contrib.sitemaps',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'mptt',
    'debug_toolbar',
    'taggit',
    'captcha',
    'django_ckeditor_5',
    'django_cleanup.apps.CleanupConfig',
    'modules.blog.apps.BlogConfig',
    'modules.system.apps.SystemConfig',
]

Пояснение:

  • Добавил 'django_cleanup.apps.CleanupConfig' в наши установленные приложения Django.

Ресайзинг/оптимизация изображения 

А теперь создадим функцию оптимизации изображения

В одном из уроков мы создавали файл utils.py в модуле system, давайте там и создадим эту функцию:

modules/system/services/utils.py

from PIL import Image

def image_optimiser(image_path, height, width):
    """
    Оптимизация изображений
    """
    img = Image.open(image_path)
    if img.mode != 'RGB':
        img = img.convert('RGB')
    if img.height > height or img.width > width:
        output_size = (height, width)
        img.thumbnail(output_size)
    img.save(image_path)

Пояснение:

  • Мы используем для оптимизации библиотеку Pillow
  • В аргументы мы передаем путь до изображения, желаемую высоту и ширину.

Теперь добавим данную функцию в профиль при сохранении:

modules/system/models/profiles.py

    def save(self, *args, **kwargs):
        """
        Сохранение параметров модели при их отсутствии заполнения
        """
        if not self.slug:
            self.slug = unique_slugify(self, self.user.username)
        if self.slug:
            self.slug = self.slug.lower()
        super().save(*args, **kwargs)

        if self.avatar:
            image_optimiser(self.avatar.path, height=300, width=300)

Почему необходимо добавить после метода def save()?

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

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

К классу нашего Profile я добавил инициализацию.

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.__avatar = self.avatar if self.pk else None

Пояснение:

  • Где в переменную self.__avatar сохраняю текущее изображение self.avatar, если существует ключ, если его нет, то значение self.__avatar = None.

Далее, меняем метод оптимизации после сохранения:

    def save(self, *args, **kwargs):
        """
        Сохранение параметров модели при их отсутствии заполнения
        """
        if not self.slug:
            self.slug = unique_slugify(self, self.user.username)
        if self.slug:
            self.slug = self.slug.lower()
        super().save(*args, **kwargs)

        if self.__avatar != self.avatar and self.avatar:
            image_optimiser_task.delay(self.avatar.path, height=300, width=300)

Пояснение:

  • Мы сравниваем переменную self.__avatar при сохранении с новым изображением, и если эти изображения разные, мы вызываем функцию оптимизации. 

На этом установка закончена, функция по оптимизации изображения добавлена, модуль django-cleanup все сделает автоматически. Мы можем доже проверить это на деле. 

Я установлю себе изображение размером 563x553px, весом 30.5 Kb. После оптимизации, вес составил 10 Kb, а размер 300x295px.

Для подробностей я скопировал аватарку оригинала в то же место, где сохранена аватарка установленная и оптимизированная на сайте.

 

Теперь я попробую ее удалить через сайт, и после удаления, аватарка исчезла, осталась лишь та, которую я скопировал сюда вручную:

Комментарии к статье 0
Комментариев нет
Форма добавления комментария (необходима регистрация)