2011-12-14 69 views
0

我已閱讀關於此主題的其他問題,但沒有一個實際回答我的問題。Django - 更改ImageField上的文件名

我讓用戶在向網站提交某個項目時上傳圖片。每個用戶可以提交多個項目,每個項目都有一個圖片。

事情是,我不想用原始文件名保存圖片。我想用項目的ID保存它。因此,如果用戶提交一個香蕉項目,這是考慮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。 這個解決方案的問題是,新實例可能還沒有一個Id,因此使用類似UUID的東西來生成文件名是有意義的,因此如果您有更多的文件名,您也可以輕鬆避免衝突一個文件的實例!看看python docs用於生成UUID!