Django удаляет неиспользуемые медиафайлы

У меня есть проект django, в котором администраторы могут загружать медиа. Когда товары продаются, они удаляются с сайта, таким образом удаляя их запись в базе данных MySQL. Однако изображения, связанные с этим элементом, остаются в файловой системе. Это не обязательно плохое поведение - я не против хранить файлы в случае, если удаление было случайным. Задача, которую я предвижу, - это два года спустя, когда пространство для хранения ограничено из-за того, что медиа-папка раздута со старыми изображениями продукта.

Кто-нибудь знает о систематическом/программном способе сортировки ВСЕХ изображений и сравнения их с соответствующими полями MySQL, удаляя любое изображение, которое НЕ имеет соответствия из файловой системы? В идеальном мире я представляю себе кнопку в django-admin, например "Clean-up unused media", который выполняет python script, способный на такое поведение. Я буду делиться тем, что мое возможное решение здесь, но то, что я ищу сейчас, - это тот, у кого есть идеи, знания ресурсов или они сделали это в какой-то момент.

Ответ 1

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

pip install django-cleanup

settings.py

INSTALLED_APPS = (
     ...
    'django_cleanup', # should go after your apps
)

Ответ 2

django-unused-media поможет вам очистить старые неиспользуемые носители командой управления.

Очень полезно, когда вы только начали использовать django-cleanup и уже имеете файлы, которые необходимо удалить. Или если у вас есть миниатюры, которые необходимо удалить из медиа-каталога.

Ответ 3

Вы можете использовать сигналы. Вместо использования os.remove() для очистки связанных файлов при удалении.

Таким образом, ваша файловая система всегда отражает ваш db. Нет необходимости в нажатии какой-либо кнопки.

Ответ 4

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

Скажем, у вас есть приложение под названием "автомобили" и модель под названием "Автомобиль".

signals.py:

# cars/signals.py

from django.conf import settings
from django.dispatch import receiver
from django.db.models.signals import post_delete

from cars.models import Car

# By adding 'Car' as 'sender' argument we only receive signals from that model
@receiver(post_delete, sender=Car)
def on_delete(sender, **kwargs):
    instance = kwargs['instance']
    # ref is the name of the field file of the Car model
    # replace with name of your file field
    instance.ref.delete(save=False)

apps.py:

# cars/apps.py
from django.apps import AppConfig

class CarConfig(AppConfig):
    name = "cars"
    def ready(self):
        import cars.signals
.

__ __ INIT ру:

default_app_config = 'cars.apps.CarConfig'

Ответ 5

Возможно, это немного поздно, но если вы также хотите узнать больше о проблемах, которые могут появиться с удалением, здесь статья в котором объясняется, как удалить их двумя способами (с фрагментами кода).

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