6

I am sending few files to the request with dropzone.js but the request.FILES.getlist() seems to be completely empty. Any possible reasons as to why?

--sorry that was just a typo in my question. it is FILES in my code.

def upload(request):
    user = request.user
    theAccount = user.us_er.account
    if request.method == "POST":
        form = uploadForm(request.POST)
        if form.is_valid():
            descriptions = request.POST.getlist('descriptions')
            count = 0 
            for f in request.FILES.getlist('file'): 
                theAccount.file_set.create(docFile = f, description = descriptions[count], dateAdded = timezone.now(), creator = user.username)
                 count = count + 1
            return HttpResponseRedirect('/home/')

        else:
            return HttpResponse("form is not valid")
    else:
        return HttpResponse('wasnt a post')

this is my template containing with the dropzone.

<form method="POST" style="border: 2px solid green;" action= "/upload/" enctype="multipart/form-data" class="dropzone">
        {% csrf_token %}
<div class="dropzone-previews"></div>


 <button  value=" submit" class="btn btn-success" type="submit" id="submit">Press to upload!</button>
        </form>
NorthCat
  • 9,643
  • 16
  • 47
  • 50
user3720855
  • 85
  • 1
  • 1
  • 5
  • You'll need to post some code snippets and show us what you have tried etc. This isn't much to go on. This also might be of some use to you: http://stackoverflow.com/questions/851336/multiple-files-upload-using-same-input-name-in-django – Karl Jun 09 '14 at 01:28
  • 3
    it's `request.FILES`, not `request.FILE` and your form should have attributes `method="post"` and `enctype="multipart/form-data"` – yedpodtrzitko Jun 09 '14 at 01:28
  • Thank you Karl. I've seen this post before and have implemented multiple files exactly how they have in that post. – user3720855 Jun 09 '14 at 01:49
  • Your form needs to be passed both dictionaries, like this `form = uploadForm(request.POST, request.FILES)` – Burhan Khalid Jun 09 '14 at 10:29
  • same problem. Anyone find solution? – Vaibhav Kadam May 31 '18 at 08:15
  • @VaibhavKadam None of this worked for me on flask 1.0.2, I used `flask.request.files.to_dict()`. – Jonas Jun 11 '18 at 03:59

3 Answers3

4

I know this is an old question, but for the sake of people landing here through google.

Dropzone.js uses ajax to upload files in a queue, so your endpoint should process the upload as a singular file not multiple.

You can access the file via request.FILES['file']

Llanilek
  • 3,386
  • 5
  • 39
  • 65
1

Instead of doing this: descriptions = request.POST.getlist ('descriptions')

Try it like this: descriptions = request.FILES.getlist ('descriptions []')

In my case it worked.

  • Welcome to Stack Overflow! While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – Yunnosch May 10 '21 at 16:24
0

The reason for that is Dropzone's way of handling the FormData name.

TLDR

To make Dropzone Django-compliant set Dropzone's paramName option to:

paramName: (index) => 'file',

Explanation

The Django way of doing multiple files upload would be adding all the files into the FormData with the same name "file" (or whatever name you gave to Dropzone paramName option) that would end up in a single MultiValueDict called "file" in request.FILES

If we look at Dropzone's documentation, it states the following for paramName:

The name of the file param that gets transferred. NOTE: If you have the option uploadMultiple set to true, then Dropzone will append [] to the name.

That documentation is outdated or misleading because Dropzone does more than that according to its source code:

// @options.paramName can be a function taking one parameter rather than a string.
// A parameter name for a file is obtained simply by calling this with an index number.
_getParamName(n) {
  if (typeof this.options.paramName === "function") {
    return this.options.paramName(n);
  } else {
    return `${this.options.paramName}${
      this.options.uploadMultiple ? `[${n}]` : ""
    }`;
  }
}

if uploadMultiple option is set to true, Dropzone will add an index between the square brackets and add them to the FormData with a name like "file[n]" where n is the index of the file.

The result in Django is a request.FILES with 'n' MultiValueDict called file[n] and you would need to call request.FILES.getlist('file[n]') for n = 0 to the number of files you sent.

Fortunately, as you can see in the comment for the function above (and that is missing from the doc), paramName can also be a function.

You can override this logic by simply ignoring the index and returning the paramName you want to handle in Django like this:

JS, Dropzone option

paramName: (n) => 'my_param_name',

Python, views.py

files = request.FILES.getlist('my_param_name')
Ultraspider
  • 156
  • 1
  • 3