Django “无法确定文件大小”错误与tempfile.TemporaryFile

9 投票
5 回答
4028 浏览
提问于 2025-04-16 22:02

我在使用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 真的是一个实际存在的文件。

撰写回答