Загрузка файлов в Django. FileField & upload_to. 1

Posted by dobrych Fri, 02 Jan 2009 10:56:00 GMT

На момент выхода версии 1.0 Django, одним из самых значительных изменений стал механизм загрузки (upload) и хранения (storage) файлов. Загрузка файлов без FileField в модели базы данных конечно очень редкий случай, поэтому начнем именно с одного из обязательных параметров FileField — upload_to.

Главная инновация — это гибкая возможность настройки этого самого upload_to. Раньше можно было только передавать строку с кодированными strftime параметрами. Тем самым можно было разбивать загруженные файлы по директориям, создаваемыми по дате, типа uploads/mp3/2008-12/uploaded.mp3. Сейчас параметром upload_to может быть и callable, т.е. к примеру функция, которая должна возвращать полный путь с именем файла, куда будет сохраняться загруженный файл. Функция должна принимать два параметра: instance и filename.

  • instance — это экземпляр объекта модели, которой и принадлежит поле с типом FileField.
  • filename — юникодное имя файла.

Эта функция будет запускаться перед сохранением в базу, поэтому если объект новый (вы не редактируете существующий объект, а создаете новый), то поле pk/id будет пустым и соотвественные Django сигналы еще не выполнены. Думаю, что с примером кода все будет наиболее хорошо понятно.

Итак функция-callback, которую мы будем использовать в upload_path:

def make_upload_path(instance, filename):
    """Generates upload path for FileField"""
    return u"uploads/%s/%s" % (instance.category.slug, filename)

Теперь пример модели с FileField:

class Upload(models.Model):
    user = models.ForeignKey(User)
    file = models.FileField(upload_to=make_upload_path)
    category = models.ForeignKey(Category)
    uploaded_date = models.DateTimeField(auto_now_add=True)

Все просто. Можно использовать множество параметров вашей модели для создания директорий и упорядочивания файлов в них. И самое главное upload_to — самый простой способ закачивания файлов с русскими (и другими юникодными) именами. Т.к. по-умолчанию Django заменяет их на символ подчеркивания, что приводит к появлению файлов типа __________.jpg. Если вы сделаете самую простую функцию с вовращением вида return u"uploads/mypath/%s" % (filename), то получите русские имена файлов после закачки.

Официальная документация Django по FileField.

FileField в Django, проблемка с удалением

Posted by dobrych Thu, 16 Nov 2006 10:52:00 GMT

Есть проблема в Django с удалением файла в FileField и ImageField из админки. Проблема давняя, а до сих пор не решенная, недавно вернулись к её обсуждению. Вот патч лежит уже три месяца как. Вчера вроде по нему появилась активность. Посмотрим…

Вот старый тикет #22 (его закрыли) и новый #2534 с более “умным” патчем.

А от себя скажу, что в модели файл получается удобнее хранить в отдельной таблице, в большинстве случаев. Т.к. при удалении ссылающегося на него объекта, сам файл можно оставить и потом использовать опять (если файл большой, то каждый раз его заливать неудобно при удалении/добавлении зависящего объекта); да плюс обычно хранится не тупо неизвестный binary файл, а что-то более интересное, нуждаещееся в описании и какой-то мета-информации, следовательно удобно было бы потом делать расширенное описание файла добавлением новых полей в таблицу по мере необходимости.

И если брать частный случай с Django, то тогда файл можно легко удалить как отдельный эелемент модели.