2009-05-12 15 views
15

im avere problemi nel caricamento di più file con lo stesso nome di input:più file caricati utilizzando lo stesso nome di input in Django

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

al fianco 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)> 
]}> 

così tutte e tre le file sono sotto un'unica richiesta. Oggetto FILES ['file']. come gestisco per ogni file caricato da qui?

+0

Stesso problema e la soluzione per un singolo elemento con molteplici: ' ' – Mark

risposta

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

EDIT: So che questo era una risposta vecchia, ma mi sono imbattuto solo ora e hanno modificato la risposta in realtà essere corretta. In precedenza suggeriva di poter iterare direttamente su request.FILES['file']. Per accedere a tutti gli elementi in un MultiValueDict, utilizzare .getlist('file'). Usando solo ['file'] restituirà solo l'ultimo valore di dati che trova per quella chiave.

+1

Qualche idea sul perché 'request.FILES ['file']' non funziona? Sono curioso. – Mark

+0

@Mark se vuoi dire che non è stato caricato alcun file, restituirà una stringa o un elenco vuoto, ma se intendi che carichi, ma non riesci a ottenere il file da 'request.FILES ['file']' s è molto probabilmente ti mancano i campi necessari nel campo 'input' nel tuo codice html. Secondo la mia esperienza, devi usare 'name =" myfile "' nel campo di input per renderlo specifico. In questo caso dovresti usare 'request.FILES ['myfile']'. L'uso di 'file' come nome nel codice html sta rendendo davvero difficile distinguere cosa sia cosa. – Ibo

+0

Un'altra cosa che è importante quando si ha a che fare con più file è includere "multiple/form-data nel tag html' form' in modo che il tag del form che avvolge il tag 'input' sia'

' – Ibo

1

Non penso che tutti e tre i file saranno sotto il singolo oggetto request.FILES['file']. request.FILES['file'] è probabile che abbia il primo file o l'ultimo file da quella lista.

È necessario dare un nome univoco i elementi di input in questo modo:

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

..per esempio.

MODIFICA: Justin's answer è meglio!

+0

Django gestisce automaticamente il caso in cui più input hanno lo stesso nome: fornisce al codice un elenco di valori anziché un singolo valore. Puoi vedere la lista nel codice che è stato pubblicato. –

+0

Quindi questo 'MultiValueDict' è il risultato forse di un wrapper per la request.FILES ['file'] oggetto allora? –

+0

Sì, request.FILES è un oggetto MultiValueDict, mentre request.GET e request.POST sono oggetti QueryDict, che sono simili. –

7

Dato tuoi URL punta a envia si potrebbe gestire più file in questo modo:

#!/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

Non si deve usare il nome file fornito dall'utente per scrivere su disco, può essere manipolato per scrivere ovunque.Usare un nome file casuale e memorizzare il nome file originale sul database solo per scopi di presentazione –

Problemi correlati