user3720855
user3720855

Reputation: 85

request.FILES.getlist('file') is empty

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>

Upvotes: 6

Views: 15403

Answers (3)

Ultraspider
Ultraspider

Reputation: 166

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')

Upvotes: 1

user15888350
user15888350

Reputation: 21

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

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

In my case it worked.

Upvotes: 2

Llanilek
Llanilek

Reputation: 3466

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']

Upvotes: 4

Related Questions