2011-07-22 17 views
9

Tengo problemas con el estándar Django FileField y tempfile.TemporaryFile. Cada vez que intento guardar un FileField con TemporaryFile, aparece el error "No se puede determinar el tamaño del archivo".Django "No se puede determinar el tamaño del archivo" error con tempfile.TemporaryFile

Por ejemplo, dado un modelo llamado Modelo, una filefield llamado FileField, y una temporaryfile nombre de archivo temporal:

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

Esto me dará el error antes mencionado. ¿Alguna idea?

+0

¿Cuál es el tipo de error? –

+0

@john Es un AttributeError. – Conan

Respuesta

2

Estaba teniendo el mismo problema y pude resolverlo en mi caso. Este es el código que Django usa para determinar el tamaño de un archivo:

 

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 
 

Por lo tanto, Django plantear una AttributeError si el archivo no existe en el disco (o tener un atributo de tamaño ya definido). Dado que la clase TemporaryFile intenta crear un archivo en la memoria en lugar de realmente en el disco, este método _get_size no funciona. Con el fin de conseguir que funcione, que tenía que hacer algo como esto:

 

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) 
 

Alternativamente (y preferiblemente), si se puede calcular el tamaño del archivo temporal que está creando, podría configurar un atributo de tamaño en el objeto TemporaryFile directamente. Debido a las bibliotecas que estaba usando, esta no era una posibilidad para mí.

11

Tuve este problema con tempfile.TemporaryFile. Cuando cambié al tempfile.NamedTemporaryFile desapareció. Creo que TemporaryFile simplemente simula ser un archivo (en algunos sistemas operativos al menos), mientras que NamedTemporaryFile realmente es un archivo.

2

tuve este problema en Heroku incluso con tempfile.NamedTemporaryFile y estaba bastante decepcionado ...

Lo resuelto utilizando puntas de Steven mediante el establecimiento de tamaño arbitrario de forma manual (sí, sucio, pero el trabajo para mí):

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)) 

Gracias!

Cuestiones relacionadas