30

i m having trouble in uploading multiple files with same input name:

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

at django side

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

so all three files are under single request.FILES['file'] object . how do i handle for each files uploaded from here?

Paolo Bergantino
  • 480,997
  • 81
  • 517
  • 436
Abu Aqil
  • 804
  • 1
  • 7
  • 12

4 Answers4

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

EDIT: I know this was an old answer, but I came across it just now and have edited the answer to actually be correct. It was previously suggesting that you could iterate directly over request.FILES['file']. To access all items in a MultiValueDict, you use .getlist('file'). Using just ['file'] will only return the last data value it finds for that key.

SmileyChris
  • 10,578
  • 4
  • 40
  • 33
Justin Voss
  • 6,294
  • 6
  • 35
  • 39
  • 1
    Any idea why it is that `request.FILES['file']` doesn't work? I'm curious. – Mark Dec 02 '12 at 02:46
  • @Mark if you mean there was no file uploaded, it will return an empty string or list, but if you mean that you upload, but still you cannot get the file from `request.FILES['file']`s it is most likely that you are missing necessary fields on the `input` field in your html code. As per my experience, you need to use `name="myfile"` in the `input field` to make it specific. In this case you should use `request.FILES['myfile']`. Using `file` as the name in the html code is making it really hard to distinguish what is what. – Ibo Sep 28 '17 at 17:57
  • 1
    One more thing that is important when dealing with multiple files is including "multiple/form-data in your html `form` tag so your form tag that wraps your `input` tag would be `
    `
    – Ibo Sep 29 '17 at 16:46
  • 1
    A decade later and this answer still works, thanks! – Mike Gostomski Apr 23 '20 at 16:44
12

Given your url points to envia you could manage multiple files like this:

#!/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()
  • 4
    You shouldn't use the user's provided filename to write on disk, it may be manipulated to write anywhere. Use a random filename and store the original filename on database for presentational purpose only – Riccardo Galli Sep 24 '13 at 22:02
1

I dont think all three files will be under the single request.FILES['file'] object. request.FILES['file'] is likely to have either the 1st file or the last file from that list.

You need to uniquely name the input elements like so:

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

..for example.

EDIT: Justin's answer is better!

Community
  • 1
  • 1
Matt Kocaj
  • 11,278
  • 6
  • 51
  • 79
  • Django automatically handles the case where multiple inputs have the same name: it hands your code a list of values instead of a single value. You can see the list in the code that was posted. – Justin Voss May 13 '09 at 04:59
  • So this 'MultiValueDict' is the result of maybe a wrapper to the request.FILES['file'] object then? – Matt Kocaj May 13 '09 at 05:18
  • Yes, request.FILES is a MultiValueDict object, while request.GET and request.POST are QueryDict objects, which are similar. – Justin Voss May 13 '09 at 06:16
0

This code is the example

    for f in request.FILES.getlist('myfile[]'):
        if request.method == 'POST' and f:
            myfile = f
            filesystem = FileSystemStorage()
            filename = filesystem.save(myfile.name, myfile)
Ali Noori
  • 21
  • 3