2009-05-12 12 views
15

im ayant du mal à télécharger plusieurs fichiers avec le même nom d'entrée:envoyer plusieurs fichiers en utilisant même nom d'entrée dans django

<input type=file name="file"> 
<input type=file name="file"> 
<input type=file name="file"> 

à côté django

print request.FILES : 

<MultiValueDict: {u'file': [ 
<TemporaryUploadedFile: captcha_bg.jpg (image/jpeg)>, 
<TemporaryUploadedFile: 001_using_git_with_django.mov (video/quicktime)>, 
<TemporaryUploadedFile: ejabberd-ust.odt (application/vnd.oasis.opendocument.text)> 
]}> 

si les trois dossiers sont en demande unique. FILES ['file'] objet. comment puis-je gérer pour chaque fichier téléchargé à partir d'ici?

+0

Même problème et solution pour un seul élément avec plusieurs: ' ' – Mark

Répondre

49
for f in request.FILES.getlist('file'): 
    # do something with the file f... 

EDIT: Je sais que c'était une vieille réponse, mais je suis tombé tout à l'heure et ont modifié la réponse à être effectivement correcte. Il a précédemment suggéré que vous pouvez itérer directement sur request.FILES['file']. Pour accéder à tous les éléments d'un MultiValueDict, vous utilisez .getlist('file'). L'utilisation de ['file'] ne renvoie que la dernière valeur de données trouvée pour cette clé.

+1

Une idée de pourquoi 'request.FILES ['file']' ne fonctionne pas? Je suis curieux. – Mark

+0

@Mark si vous voulez dire qu'il n'y avait pas de fichier téléchargé, il va retourner une chaîne ou une liste vide, mais si vous voulez dire que vous téléchargez, mais vous ne pouvez toujours pas obtenir le fichier 'request.FILES ['file']' s le plus probable que vous manquiez les champs nécessaires dans le champ 'input' de votre code html. Selon mon expérience, vous devez utiliser 'name =" myfile "' dans le champ 'input 'pour le rendre spécifique. Dans ce cas, vous devez utiliser 'request.FILES ['monfichier']'. Utiliser 'file' comme nom dans le code html rend vraiment difficile de distinguer ce qui est quoi. – Ibo

+0

Une autre chose qui est importante lorsque vous manipulez plusieurs fichiers est d'inclure "multiple/form-data dans votre tag html' form' de sorte que votre tag de formulaire qui enveloppe votre tag 'input' serait'

' – Ibo

1

Je ne pense pas que tous les trois fichiers seront sous l'objet unique request.FILES['file']. request.FILES['file'] est susceptible d'avoir le 1er fichier ou le dernier fichier de cette liste.

Vous devez attribuer un nom unique les éléments d'entrée comme ceci:

<input type=file name="file1"> 
<input type=file name="file2"> 
<input type=file name="file3"> 

..pour exemple.

EDIT: Justin's answer c'est mieux!

+0

Django gère automatiquement le cas où plusieurs entrées ont le même nom: il donne à votre code une liste de valeurs au lieu d'une seule valeur. Vous pouvez voir la liste dans le code qui a été posté. –

+0

Donc, ce 'MultiValueDict' est le résultat de peut-être un wrapper à l'objet request.FILES ['file'] alors? –

+0

Oui, request.FILES est un objet MultiValueDict, tandis que request.GET et request.POST sont des objets QueryDict, qui sont similaires. –

7

Étant donné vos points d'URL pour envia vous pouvez gérer plusieurs fichiers comme ceci:

#!/usr/bin/env python 
# -*- coding: UTF-8 -*- 
from django.http import HttpResponseRedirect 

def envia(request): 
    for f in request.FILES.getlist('file'): 
     handle_uploaded_file(f) 
    return HttpResponseRedirect('/bulk/') 

def handle_uploaded_file(f): 
    destination = open('/tmp/upload/%s'%f.name, 'wb+') 
    for chunk in f.chunks(): 
     destination.write(chunk) 
    destination.close() 
+0

Vous ne devez pas utiliser le nom de fichier fourni par l'utilisateur pour l'écrire sur le disque, il peut être manipulé pour écrire n'importe où Utilisez un nom de fichier aléatoire et stockez le nom de fichier original dans la base de données –