@yeputons

Django — как настроить удаление ненужных файлов (из FileField) при удалении/изменении модели?

Добрый вечер.

Есть модель, в ней есть несколько полей типа FileField и ImageField.

Имеется ли какой-нибудь документированный и короткий способ сделать так, чтобы:

а)При удалении модели автоматом удалялись все связанные с ней файлы

б)При изменении модели автоматом удалялись старые версии файлов, если загружены новые (или, соответственно, не менялось ничего).


Оба пункта решаются сниппетом с обработкой post_delete и pre_save событий. Но в нём я делаю дополнительное обращение к базе, чтобы узнать местоположение старого файла.

Из прочих «вариантов» есть расширение стандартного дескриптора, чтобы сохранять путь к старому файлу прямо в модели. Но это уже сложнее, чем один запрос к БД.


Вопросов два:

1)можно ли решить пункты а) и б) встроенными средствами

2)какие еще красивые решения вы видите?
  • Вопрос задан
  • 5451 просмотр
Решения вопроса 1
homm
@homm
Для начала нужно сказать, для чего вообще было введен такое поведение. Дело в том, что удаление объекта (вы, кстати, ошибочно называете объекты моделями) еще не означает, что он ушел и больше не вернется. Удаление вполне может происходить в транзакции, которая после откатится. Разработчики Джанги верно определили, что это задача не выполнения приложения, а его администрирования. Поэтому лучшим решением будет создать для вашего приложения действие менеджмента, которое будет запускаться по крону. В нем вы можете выбирать все реально существующие файлы и копировать их в отдельное место, после чего менять это место с папкой, в которую закачиваются файлы. Если файлы хранятся на локальной машине, лучше создавать симлинки, сэкономите и время и место на диске.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
un1t
@un1t
Не знаю актуальна ли еще проблема, но для меня она была таковой все это время. В итоге я написал приложение которое занимаются удалением старых файлов. github.com/un1t/django-cleanup
Ответ написан
Комментировать
Sergei_Erjemin
@Sergei_Erjemin
Улыбайся, будь самураем...
Тут посоветовали django-cleanup -- это действительно хорошее решение, но когда в каких-то моделях нужно удалять, а в других не нужно, или даже разное поведение с файлами в разных местах (где-то удалять файлы, а где-то оставлять), то есть другое решение:

Допустим есть модель:
class tb_icons(models.Model):
    image = models.ImageField(max_length=128, verbose_name=u"картинка")
    # ...
    # ...


Если хочешь удалить запись из таблицы tb_icons и сопутствующий файл из image делаешь так (например, для удаления первой записи):

tb_icons.objects.get(id=1).image.delete(save=True)
tb_icons.objects.get(id=1).delete()


Соответственно если save=False файл удаляться не будет.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы