0

I am trying to upload multiple files by using Flask, HTML and JS. However, when I try to retrieve their names in the route of Flask the list if empty.

This is the flask route (named upload):

@app.route("/upload", methods=["POST", "GET"])
def upload():
    if request.method == "POST":
        return str(request.files)

Then in mu upload.html I have the following script:

<form action="" method="POST" enctype="multipart/form-data">
        <div style="padding-left: 7%">
            <div class="file-upload">
                <input class="file-upload__input" type="file" name="files" id="files" multiple>
                <button class="file-upload__button" type="button">Choose File(s)</button>
                <span class="file-upload__label" style="color: white">No file(s) selected</span>
            </div>
            <script>
                Array.prototype.forEach.call(
                    document.querySelectorAll(".file-upload__button"),
                    function(button) {
                        const hiddenInput = button.parentElement.querySelector(
                            ".file-upload__input"
                            );
                        const label = button.parentElement.querySelector(".file-upload__label");
                        const defaultLabelText = "No file(s) selected";

            // Set default text for label
            label.textContent = defaultLabelText;
            label.title = defaultLabelText;

            button.addEventListener("click", function() {
                hiddenInput.click();
            });

            hiddenInput.addEventListener("change", function() {
                const filenameList = Array.prototype.map.call(hiddenInput.files, function(
                    file
                    ) {
                    return file.name;
                });

                label.textContent = filenameList.join(", ") || defaultLabelText;
                label.title = label.textContent;
            });
        }
        );
    </script>
<div style="padding-top: 75px; padding-left: 7%; padding-bottom: 10%">
    <input type="submit" value="Save to Cloud" name="submit" class="file-upload__button">
</div >
</form>

When I launch it and the method is POST I have the following output : enter image description here

How can I have access to the name of the files I uploaded please ?

This is what my interface looks like :

enter image description here and

enter image description here

UPDATE:

When I do print(request.files) before the return I get :

ImmutableMultiDict([('files', <FileStorage: 'test.csv' ('text/csv')>)]) 

where test.csv is indeed the correct name of the file.

Please let me know if you have any ideas of what I am doing wrong

Christian K.
  • 2,785
  • 18
  • 40
lolaa
  • 181
  • 1
  • 4
  • 11
  • You need to add the code under `/upload` for when the request is not a `POST`. When you have `action=""`, that goes to the current url. So you need to make sure that is also `/upload`. Also, `print(request.files)` before the `return` to check what you have accessible. – GAEfan Aug 03 '20 at 15:10
  • I get this when I print : ImmutableMultiDict([('files', )]) and test.csv is the correct name so how can I retrieve it now and return it on my interface ? – lolaa Aug 03 '20 at 15:14
  • Please update your question with this new info. What are you trying to do with the uploaded files? If you want the current page to say something like "the following files were uploaded...", you should submit the form via an ajax call. If you want to display them on a new page, use `render_template()` in the view. – GAEfan Aug 03 '20 at 15:23
  • I've spent a lifetime trying to re-create this, and had trouble getting `ImmutableMultiDict` to play nicely. I've been through this before though, so can suggest using [dropzone.js](https://www.dropzonejs.com/) to implement the frontend. Here's a [gist I wrote](https://gist.github.com/vulcan25/8e9444750426cdc7eb2cfd0a0f50a05c) which demonstrates simple usage with flask; each file uses a single request so your `upload` route can be designed to handle a single file. This also supports drag and drop. Feel free to comment that gist with any issues :) – v25 Aug 03 '20 at 16:22
  • I feel your `label.textContent = defaultLabelText;` line is setting the text to `"No file(s) selected"` – Sowjanya R Bhat Aug 03 '20 at 16:24
  • Is this probably what you are looking for? https://stackoverflow.com/a/36257330/6016860 – Pratibha Gupta Aug 11 '21 at 01:12

0 Answers0