6

Here is my code for multiple files upload:

HTML CODE:

Browse <input type="file" name="pro_attachment1" id="pro_attachment1" multiple> 

PYTHON CODE:

pro_attachment = request.files.getlist('pro_attachment1') for upload in pro_attachment: filename = upload.filename.rsplit("/")[0] destination = os.path.join(application.config['UPLOAD_FOLDER'], filename) print "Accept incoming file:", filename print "Save it to:", destination upload.save(destination) 

But it uploads a single file instead of multiple files.

2
  • What is the length of the pro_attachment list? Commented Feb 26, 2016 at 15:16
  • user can select multiple files.length is according to they select the files Commented Mar 1, 2016 at 2:30

2 Answers 2

16

How to

In the template, you need to add mulitple attribute in upload input:

<form method="POST" enctype="multipart/form-data"> <input type="file" name="photos" multiple> <input type="submit" value="Submit"> </form> 

Then in view function, the uploaded files can get as a list through request.files.getlist('photos'). Loop this list and call save() method on each item (werkzeug.datastructures.FileStorage) will save them at given path:

import os from flask import Flask, request, render_template, redirect app = Flask(__name__) app.config['UPLOAD_PATH'] = '/the/path/to/save' @app.route('/upload', methods=['GET', 'POST']) def upload(): if request.method == 'POST' and 'photo' in request.files: for f in request.files.getlist('photo'): f.save(os.path.join(app.config['UPLOAD_PATH'], f.filename)) return 'Upload completed.' return render_template('upload.html') 

Furthermore, you may need to use secure_filename() to clean filename:

# ... from werkzeug.utils import secure_filename # ... for f in request.files.getlist('photo'): filename = secure_filename(f.filename) f.save(os.path.join(app.config['UPLOAD_PATH'], filename)) # ... 

You can also generate a random filename with this method.

Full demo

View:

import os from flask import Flask, request, render_template from werkzeug.utils import secure_filename app = Flask(__name__) app.config['UPLOAD_PATH'] = '/the/path/to/save' @main.route('/upload', methods=['GET', 'POST']) def upload(): form = UploadForm() if form.validate_on_submit() and 'photo' in request.files: for f in request.files.getlist('photo'): filename = secure_filename(f.filename) f.save(os.path.join(app.config['UPLOAD_PATH'], filename)) return 'Upload completed.' return render_template('upload.html', form=form) 

Form:

from flask_wtf import FlaskForm from wtforms import SubmitField from flask_wtf.file import FileField, FileAllowed, FileRequired class UploadForm(FlaskForm): photo = FileField('Image', validators=[ FileRequired(), FileAllowed(photos, 'Image only!') ]) submit = SubmitField('Submit') 

Template:

<form method="POST" enctype="multipart/form-data"> {{ form.hidden_tag() }} {{ form.photo(multiple="multiple") }} {{ form.submit }} </form> 

More

For better upload experience, you can try Flask-Dropzone.

Sign up to request clarification or add additional context in comments.

1 Comment

How do I check that the user actually uploaded a file?
3

Your code looks perfect. I think the only mistake your making is splitting and taking the first value. And also i dont know about the rsplit(), but the split() works perfect for me.

HTML CODE

 
<input id="upload_img" name="zip_folder" type="file" multiple webkitdirectory >

PYTHON CODE

@app.route('/zipped',methods = ['GET', 'POST']) def zipped(): if request.method == 'POST': f = request.files.getlist("zip_folder") print f for zipfile in f: filename = zipfile.filename.split('/')[1] print zipfile.filename.split('/')[1] zipfile.save(os.path.join(app.config['ZIPPED_FILE'], filename)) return render_template('final.html') 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.