2011-07-22 90 views
9

我遇到了標準Django FileField和tempfile.TemporaryFile的問題。每當我嘗試使用TemporaryFile保存FileField時,都會出現「無法確定文件大小」錯誤。Django「Unable to determine the file's size」error with tempfile.TemporaryFile

例如,給定一個名爲型號模型,一個名爲的FileField FileField字段,以及一個名爲臨時文件temporaryfile:

Model.FileField.save('foobar', django.core.files.File(TempFile), save=True) 

這會給我前面提到的錯誤。有什麼想法嗎?

+0

什麼是錯誤類型? –

+0

@john這是一個AttributeError。 – Conan

回答

2

我有同樣的問題,並能解決它的情況。這是Django使用以確定一個文件的大小的代碼:

 

def _get_size(self): 
    if not hasattr(self, '_size'): 
    if hasattr(self.file, 'size'): 
     self._size = self.file.size 
    elif os.path.exists(self.file.name): 
     self._size = os.path.getsize(self.file.name) 
    else: 
     raise AttributeError("Unable to determine the file's size.") 
    return self._size 
 

因此,Django將引發一個AttributeError如果該文件不存在於磁盤上(或已經定義的大小屬性)。由於TemporaryFile類嘗試在內存中創建文件而不是實際在磁盤上,因此此_get_size方法不起作用。爲了得到它的工作,我不得不做這樣的事情:

 

import tempfile, os 
# Use tempfile.mkstemp, since it will actually create the file on disk. 
(temp_filedescriptor, temp_filepath) = tempfile.mkstemp() 
# Close the open file using the file descriptor, since file objects 
# returned by os.fdopen don't work, either 
os.close(temp_filedescriptor) 

# Open the file on disk 
temp_file = open(temp_filepath, "w+b") 

# Do operations on your file here . . . 

modelObj.fileField.save("filename.txt", File(temp_file)) 

temp_file.close() 
# Remove the created file from disk. 
os.remove(temp_filepath) 
 

或者(最好),如果你可以計算出你所創建的臨時文件的大小,你可以設置一個大小屬性直接在TemporaryFile對象上。由於我使用的圖書館,這不是我的可能性。

11

我有這個問題tempfile.TemporaryFile。當我切換到tempfile.NamedTemporaryFile它消失了。我相信TemporaryFile只是模擬一個文件(至少在某些操作系統上),而NamedTemporaryFile確實是一個文件。

2

我對的Heroku即使tempfile.NamedTemporaryFile這個問題,是相當失望......

我解決它使用史蒂芬的提示通過手動設置任意大小(是的,骯髒的,但對我的工作):

from django.core.files import File 
from django.core.files.temp import NamedTemporaryFile 

img_temp = NamedTemporaryFile() 
# Do your stuffs ... 
img_temp.flush() 
img_temp.size = 1024 

media.thumbnail.save('dummy', File(img_temp)) 

謝謝!

相關問題