Reputation: 35
I'm trying to upload multiple images using WTForms in Flask using "MultiFileField, however, it returns a string instead of the file object. So I tried using the below:
request.files.getlist(form.upload_field.data)
But it returns an empty list, so anyway I can handle this to save the photos to a directory
Upvotes: 0
Views: 386
Reputation: 10861
There is documentation of file uploads with Flask here, and you are going about it the right way through accessing the request.files
object. I've come across two ways to get an empty list back from there:
1. enctype
form html attribute not set
Here's an example template that renders the MultipleFileField()
:
template = """
<form action="" method="POST" enctype="multipart/form-data">
{{ form.upload_field() }}
{{ form.submit() }}
</form>
"""
If I remove the enctype=...
part, the list of files returns empty, where it otherwise would have values. A page on the internet says:
This value is required when you are using forms that have a file upload control
2. Passing the wrong Key to request.files.getlist()
request.files
is a werkzeug.MultiDict
, which is a mapping of keys to values, designed to handle having multiple values for the same key.
Using the same form template as above, inspecting the keys of request.files
(print(list(request.files.keys()))
) upon POST reveals ['upload_field']
.
werkzeug.MultiDict.getlist
has a single required parameter:
key - The key to be looked up.
So the only key in the MultiDict instance at this point is the string 'upload_field'
, if we want to get anything back from the getlist
method, this needs to be the key that we pass to getlist
. In your example code, you pass the value of the form.upload_field.data
attribute (which in my tests is None
). Change that to 'upload_field'
and you should be away.
Here's a working minimal example that will print the result of calling request.files.getlist()
upon form submit. Run the script, visit http://127.0.0.1:5000
in your browser, upload a couple of files and watch the terminal output.
from flask import Flask, render_template_string, request
from wtforms import Form, MultipleFileField, SubmitField
app = Flask(__name__)
class MyForm(Form):
upload_field = MultipleFileField()
submit = SubmitField()
template = """
<form action="" method="POST" enctype="multipart/form-data">
{{ form.upload_field() }}
{{ form.submit() }}
</form>
"""
@app.route("/", methods=["GET", "POST"])
def route():
form = MyForm()
if request.method == "POST":
print(request.files.getlist("upload_field"))
return render_template_string(template, form=form)
if __name__ == "__main__":
app.run(debug=True)
Upvotes: 5