simple name inmemoryuploadedfile framework form example python django file-upload file-storage

python - name - Cómo copiar el objeto InMemoryUploadedFile al disco



upload image django example (4)

Intento atrapar un archivo enviado con el formulario y realizar algunas operaciones antes de que se guarde. Entonces necesito crear una copia de este archivo en el directorio temporal, pero no sé cómo llegar a él. Las funciones de Shutil no pueden copiar este archivo, ya que no hay una ruta hacia él. Entonces, ¿hay alguna manera de hacer esta operación de otra manera?

Mi código :

image = form.cleaned_data[''image''] temp = os.path.join(settings.PROJECT_PATH, ''tmp'') sourceFile = image.name # without .name here it wasn''t working either import shutil shutil.copy(sourceFile, temp)

Que plantea:

Exception Type: IOError at /
Exception Value: (2, ''No such file or directory'')

Y la depuración:

# (..)/views.py in function 67. sourceFile = image.name 68. import shutil 69. shutil.copy2(sourceFile, temp) ... # (..)/Python26/lib/shutil.py in copy2 92. """Copy data and all stat info ("cp -p src dst"). 93. 94. The destination may be a directory. 95. 96. """ 97. if os.path.isdir(dst): 98. dst = os.path.join(dst, os.path.basename(src)) 99. copyfile(src, dst) ... 100. copystat(src, dst) 101. ▼ Local vars Variable Value dst u''(..)//tmp//myfile.JPG'' src u''myfile.JPG'' # (..)/Python26/lib/shutil.py in copyfile 45. """Copy data from src to dst""" 46. if _samefile(src, dst): 47. raise Error, "`%s` and `%s` are the same file" % (src, dst) 48. 49. fsrc = None 50. fdst = None 51. try: 52. fsrc = open(src, ''rb'') ... 53. fdst = open(dst, ''wb'') 54. copyfileobj(fsrc, fdst) 55. finally: 56. if fdst: 57. fdst.close() 58. if fsrc: ▼ Local vars Variable Value dst u''(..)//tmp//myfile.JPG'' fdst None fsrc None src u''myfile.JPG''


Aquí hay otra forma de hacerlo con python''s mkstemp :

### get the inmemory file data = request.FILES.get(''file'') # get the file from the curl ### write the data to a temp file tup = tempfile.mkstemp() # make a tmp file f = os.fdopen(tup[0], ''w'') # open the tmp file for writing f.write(data.read()) # write the tmp file f.close() ### return the path of the file filepath = tup[1] # get the filepath return filepath


Como lo menciona @ups , al cargar archivos de gran tamaño, no desea obstruir la memoria del sistema con data.read() .

De los documentos de Django :

El bucle sobre UploadedFile.chunks() lugar de usar read() asegura que los archivos grandes no abrumen la memoria de su sistema

from django.core.files.storage import default_storage filename = "whatever.xyz" # received file name file_obj = request.data[''file''] with default_storage.open(''tmp/''+filename, ''wb+'') as destination: for chunk in file_obj.chunks(): destination.write(chunk)

Esto guardará el archivo en MEDIA_ROOT/tmp/ como su default_storage a menos que se indique lo contrario.


Lo mejor que puede hacer es escribir un controlador de carga personalizado. Ver los docs . Si agrega un controlador "file_complete", puede acceder al contenido del archivo independientemente de tener un archivo de memoria o un archivo de ruta temporal. También puede usar el método "receive_data_chunck" y escribir su copia dentro de él.

Saludos


This es una pregunta similar, podría ayudar.

import os from django.core.files.storage import default_storage from django.core.files.base import ContentFile from django.conf import settings data = request.FILES[''image''] # or self.files[''image''] in your form path = default_storage.save(''tmp/somename.mp3'', ContentFile(data.read())) tmp_file = os.path.join(settings.MEDIA_ROOT, path)