J'essaie d'attraper un fichier envoyé avec le formulaire et d'effectuer certaines opérations dessus avant qu'il ne soit enregistré. J'ai donc besoin de créer une copie de ce fichier dans le répertoire temp, mais je ne sais pas comment y accéder. Les fonctions de Shutil ne parviennent pas à copier ce fichier, car il n'y a aucun chemin d'accès. Existe-t-il un moyen de faire cette opération d'une autre manière?
Mon code:
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)
Ce qui soulève:
Exception Type: IOError at /
Exception Value: (2, 'No such file or directory')
Et le débogage:
# (..)\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'
This est une question similaire, cela pourrait aider.
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)
Comme mentionné par @ Sławomir Lenart , lors du téléchargement de gros fichiers, vous ne voulez pas obstruer la mémoire système avec une data.read()
.
De documents Django :
Faire une boucle sur
UploadedFile.chunks()
au lieu d'utiliserread()
garantit que les fichiers volumineux ne surchargent pas la mémoire de votre système
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)
Cela enregistrera le fichier à MEDIA_ROOT/tmp/
comme votre default_storage
le fera sauf indication contraire.
La meilleure solution consiste à écrire un gestionnaire de téléchargement personnalisé. Voir docs . Si vous ajoutez un gestionnaire "file_complete", vous pouvez accéder au contenu du fichier indépendamment de la présence d'un fichier mémoire ou d'un fichier de chemin temporaire. Vous pouvez également utiliser la méthode "receive_data_chunck" et y écrire votre copie.
Cordialement
Voici une autre façon de le faire avec le mkstemp
de python:
### 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