Django «Невозможно определить размер файла» ошибка с временным файлом. - PullRequest
9 голосов
/ 22 июля 2011

У меня проблемы со стандартным Django FileField и tempfile.TeoraryFile.Всякий раз, когда я пытаюсь сохранить FileField с помощью TemporaryFile, я получаю сообщение об ошибке «Невозможно определить размер файла».

Например, для модели с именем Model, поле для файла с именем FileField и временный файл с именем TempFile:

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

Это даст мне вышеупомянутую ошибку.Есть мысли?

Ответы [ 3 ]

11 голосов
/ 27 ноября 2011

У меня была эта проблема с tempfile.TemporaryFile.Когда я переключился на tempfile.NamedTemporaryFile, он ушел.Я считаю, что TemporaryFile просто симулирует быть файлом (по крайней мере, в некоторых операционных системах), тогда как NamedTemporaryFile действительно является файлом.

2 голосов
/ 04 декабря 2012

У меня была эта проблема на 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))

Спасибо!

2 голосов
/ 27 ноября 2011

У меня была такая же проблема, и я смог решить ее для моего случая. Это код, который 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. Из-за библиотек, которые я использовал, это было невозможно для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...