Django “无法确定文件大小”错误与tempfile.TemporaryFile
我在使用Django的标准FileField和tempfile.TemporaryFile时遇到了一些问题。每当我尝试用TemporaryFile保存一个FileField时,就会出现“无法确定文件大小”的错误。
比如,我有一个叫Model的模型,一个叫FileField的文件字段,还有一个叫TempFile的临时文件:
Model.FileField.save('foobar', django.core.files.File(TempFile), save=True)
这样做就会出现之前提到的错误。有没有什么想法可以解决这个问题?
5 个回答
2
我在Heroku上遇到了这个问题,即使使用了tempfile.NamedTemporaryFile
,我还是感到很失望...
我按照Steven的建议解决了这个问题,手动设置了一个任意大小(是的,这种方法有点不太干净,但对我有效):
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))
谢谢!
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
真的是一个实际存在的文件。