2011-12-14 4 views
0

Я прочитал другие вопросы по этой теме, но никто не отвечает на мой вопрос.Django - Изменение имени файла на ImageField

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

Дело в том, что я не хочу сохранять изображение с оригинальным именем файла. Я хочу сохранить его с идентификатором элемента. Таким образом, если пользователь отправляет товар Banana, который дается ID 5 и имя файла

banana.jpg 

Я хочу, чтобы сохранить как

site_media/items/5.jpg 

и не

site_media/items/banana.jpg 

что и Django делает автоматически.

Теперь дело в том, что когда я получаю данные POST от формы, я уже сохраняю изображение как site_media/items/item_ID.jpg. Однако, когда я пытаюсь отобразить поле item.picture на шаблоне, он пытается получить доступ к

site_media/items/banana.jpg 

вместо

site_media/items/5.jpg 

Что является файл, который на самом деле существует. Поэтому я получаю неработающую ссылку.

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

Кроме того, естественно, я бы предпочел, если есть решение, в котором я просто изменяю имя файла при сохранении, вместо того, чтобы удалять файл с исходным именем файла и сохранять копию с новым именем, для эффективной практики и эффективности.

Кто-нибудь может мне помочь? Спасибо.

Модели Код:

class Item(...): 
    ... 
picture = models.ImageField(
    upload_to="site_media/items/", 
    max_length=512, 
    null=True, 
    default='' 
) 

Вот функция обработки формы POST:

item = Item.objects.create(... data from form) 
try: 
    picture = FILES['picture'] 
    print str(picture) 

    destination = open('site_media/items/'+str(item.id)+".png", 'wb+') 
    for chunk in picture.chunks(): 
     destination.write(chunk) 
    destination.close() 

    item.picture = picture 
except Exception: 
    messages.error(request, "Picture for item not loaded successfully") 

ответ

1

Найдено решение. Таким образом, проблема заключается в том, что request.FILES содержит другое имя файла из сохраненного имени файла.Так что я просто изменил request.FILES имени файла перед сохранением изображения, как это:

picture = FILES['picture'] 
FILES['picture'].name = str(item.id) + '.png' 

# ...save as normal 
+2

Этого метода потерпит неудачу для новых элементов, которые еще не сохранены в базу данных, и, следовательно, приведет к повторяющемуся коду. Использование обратного вызова 'upload_to' действительно не так сложно. – sleblanc

6

Вы можете обеспечить обратный вызов к upload_to аргумента на поле изображения. Указанной функции будет предоставлен текущий экземпляр, который будет сохранен. См. Например. this example. Проблема с этим решением заключается в том, что у нового экземпляра может отсутствовать идентификатор, поэтому имеет смысл использовать что-то вроде UUID для генерации имени файла, поэтому вы также можете легко избежать столкновений, если у вас будет больше, чем один файл для экземпляра! Посмотрите на python docs для генерации UUID!

Смежные вопросы