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