2012-04-10 23 views
4

我想使用硬鏈接來複制文件,其中的文件存儲爲Django FileField。我想使用硬鏈接來節省空間和複製時間(預計不會對原始文​​件或副本進行更改)。不過,當我嘗試從下面的代碼片段調用new_file.save()時,出現了一些奇怪的錯誤。Django:複製FileFields

AttributeError: 'file' object has no attribute '_committed' 

我的想法是做硬鏈接後,我就可以打開鏈接的文件,並將其存儲到Django的新文件實例的FileFile。我在這裏錯過了一步嗎?

models.py

class File(models.Model): 
    stored_file = models.FileField() 

elsewhere.py

import os 

original_file = File.objects.get(id=1) 
original_file_path = original_file.file.path 

new_file = File() 
new_file_path = '/path/to/new/file' 

os.makedirs(os.path.realpath(os.path.dirname(new_file_path))) 
os.link(original_file_path, new_file_path) 
new_file.stored_file = file(new_file_path) 
new_file.save() 

回答

8

沒有必要創建硬鏈接,只需複製的文件持有者:

new_file = File(stored_file=original_file.stored_file) 
new_file.save() 

更新

如果要指定文件的FileField或ImageField的,你可以簡單地

new_file = File(stored_file=new_file_path) 
# or 
new_file = File() 
new_file.stored_file = new_file_path 
# or 
from django.core.files.base import File 
# from django.core.files.images import ImageFile # for ImageField 
new_file.stored_file = File(new_file_path) 

現場接受即basestring或文件()實例路徑,在你的問題的代碼使用文件()和因此不被接受。

+0

感謝您的回覆okm。我選擇硬鏈接的原因是因爲我想用新的File()實例存儲不同的文件路徑。我想這個要求在上面的代碼片段中並不明顯 - 我試圖儘可能簡化它 - 但是我正在基於與File()模型實例相關的uuid創建文件名。當我複製File()模型實例時,我希望底層的stored_file路徑與新的File()實例的uuid匹配。這就是爲什麼我傾向於硬鏈接。 – 2012-04-10 18:11:17

+0

@JoeJ我明白了,那麼你的回答是正確的。更新了我的答案 – okm 2012-04-11 02:40:06

2

我想我解決了這個問題,但不知道它爲什麼起作用。我將文件對象封裝在「DjangoFile」類中(作爲DjangoFile導入,以避免與我之前定義的File模型衝突)。

from django.core.files.base import File as DjangoFile 

... 
new_file.stored_file = DjangoFile(file(new_file_path)) 
new_file.save() 

接近這似乎保存文件確定。