2009-07-27 49 views
121

我試圖設置我的上傳,以便如果用戶joe上傳文件,它將轉到MEDIA_ROOT/joe,而不是將所有人的文件轉到MEDIA_ROOT。問題是我不知道如何在模型中定義這個。這是它目前的樣子:Django FileField with upload_to在運行時確定

class Content(models.Model): 
    name = models.CharField(max_length=200) 
    user = models.ForeignKey(User) 
    file = models.FileField(upload_to='.') 

所以我想要的是'。'而不是'。'作爲upload_to,讓它成爲用戶的名字。

我知道,從Django 1.0開始,您可以定義自己的函數來處理upload_to,但是該函數不知道用戶是誰,所以我有點迷路。

感謝您的幫助!

回答

242

你可能已經閱讀the documentation,所以這裏是一個簡單的例子,使其意義:

def content_file_name(instance, filename): 
    return '/'.join(['content', instance.user.username, filename]) 

class Content(models.Model): 
    name = models.CharField(max_length=200) 
    user = models.ForeignKey(User) 
    file = models.FileField(upload_to=content_file_name) 

正如你所看到的,你甚至不需要使用給出的文件名 - 你可以重寫如果你喜歡,也可以在你的upload_to中調用。

+0

是的,它可能屬於文檔 - 這是一個合理的關於IRC的常見問題 – SmileyChris 2009-07-28 09:22:00

+2

這是否適用於ModelForm?我可以看到該實例具有類模型的所有屬性,但沒有值(只是字段名的一個str)。在模板中,用戶是隱藏的。我可能需要提交一個問題,我一直在Google上搜索幾個小時。 – mgag 2010-03-07 16:46:17

+0

是的,它的工作原理,是的,你應該問一個新的問題(或在#django irc上尋求幫助) – SmileyChris 2010-03-07 22:51:20

11

這確實有幫助。爲了更簡潔起見,決定在我的情況下使用lambda:

file = models.FileField(
    upload_to=lambda instance, filename: '/'.join(['mymodel', str(instance.pk), filename]), 
) 
3

關於使用'實例'對象的pk值的說明。根據文檔:

在大多數情況下,這個對象將不會被保存到數據庫中還,所以如果使用默認的下拉列表AutoField,它可能尚未有其主鍵字段的值。

因此,使用pk的有效性取決於您的特定模型是如何定義的。