A shelter from pigs on the wing
DMZ
дневник заведен 09-08-2004
постоянные читатели [32]
3 CaHuTaPa, 517design, Arde, Art`Is, aviabaza, BlackDrago, CyberJoe, DeadMorozz, Depeche Mode, DMZ, d_r, Ewige, glv12 Marla Zinger, goldenandy, Grimble, Hydralisk, Jude, Katrine Himitsu, Leave-me-alone, MISTIK, My3a, Nash, Nicholas Hawkwood, Pingvin, Riskoff, VorteX DrAgON, Wolfram, Букля_, достало, Муть, Рика, Эль
закладки:
цитатник:
дневник:
местожительство:
Красноярск, Россия, Сибирь
интересы [24]
программирование, C++, Depeche Mode, Star Wars, perl, DVD, JavaScript, FAR, lost, 80е, Half Life 2, долго спать, Miami Vice, веб-роботы, кентаврицы
антиресы [9]
грибы, грейпфрутовый сок, мёртвые люди, табличка обед, долго спать
Среда, 6 Мая 2009 г.
09:49

Еще интересная штука — если вдруг на файловой системе появилась ошибка и файл не удалился (например кто-то умный забрал права), то запись из базы все равно удаляется. Хорошо бы как-нибудь это дело поправить

Полное решение, правда, требует глубокого изучения всех возможных вариантов, но вот интересный маленький способ. Имеется вьюшка, которая в итоге должна будет удалить объект из базы. Пробуем удалить. При ошибках в файловой подсистеме Django выкинет OSError, но все равно удалит файл.

Точнее Django сначала удалит запись и только потом будет пытаться стереть файл

Красивого способа обойты это я пока не нашел, но можно привлечь базу данных. А именно: сделать откат транзакции, если была ошибка OSError. Вобщем план таков: запрещаем автоматическое подтверждение транзакции. Если не было OSError подтверждает вручную, иначе откатываем вручную

@transaction.commit_manually
def deletedocument(request, ...):
    ....

    try:
        object.delete()
    except OSError:
        transaction.rollback()
    else:
        transaction.commit()
09:37
Надо бы тоже какие-нибудь интересные куски кода выкладывать, а то в гугле не так то просто ищутся интересные вещи Стандартный upload в Django может легко сам раскидывать закачиваемые файлы по папкам
Но когда файл удаляется, то папки остаются живы
Обычно на это пофиг, так как на сайте живет не один файл и папку удалять не приходится
Но иногда, когда дерево слишком большое или у программиста паталогическая чистоплотность охота автоматом удалять пустые папки
Вот у меня файлы живут в папках вида /2009/05/06/a29ac73569edd9e329471d9d232d59a9/protokol-8.doc

Так как Python и Django ужас как ООП, то самый красивый и грамотный метод — это отсубкласситься от родного класса и переопределить нужную функцию. Удаление файла проиходит в Storage, так что надо написать свой. От самого Storage субкласситься конечно не надо, ибо обычными файловыми системами заведует FileSystemStorage. Вот от него мы и будем делать нашего ребенка.

import os
from django.core.files.storage import FileSystemStorage

class FileSystemStorageFoldered(FileSystemStorage ):
  def delete(self, name, *args, **kwargs ):
    super(FileSystemStorageFoldered, self ).delete(name, *args, **kwargs )
    try:
      os.removedirs(os.path.dirname(self.path(name )))
    except OSError:
      pass
Сначала мы удаляем сам файл методом родительского класса, а потом удаляем и сами папки. Если папки не пустые, то выкидывается исключение OSError, но в данном случае мы его просто игнорируем, так как именно такое поведение нам и нужно

А потом надо просто сказать в нашей модели, что надо использовать новый Storage вместо обычного

 file = models.FileField(upload_to = upload_callback_document,\
  storage = FileSystemStorageFoldered )
Понедельник, 23 Июня 2008 г.
05:17
Чем мне уже не нравится PHP, но нравится Perl.
А вообще надо будет написать рабочий проект на Python+Django или Ruby+RubyOnRails. Ибо надо двигаться вперед.
Закрыть