File not uploading with Flask-wtforms in cookiecutter-flask app
Looking through the documentation, the link you provided indicates that the data
field of csv
is an instance of werkzeug.datastructures.FileStorage
. The documentation for FileStorage.save()
suggests that:
If the destination is a file object you have to close it yourself after the call.
Could it be that because you aren't closing the file, it isn't being written to disk?
Try this:
from flask import requestif uploadform.validate_on_submit(): if 'csv' in request.files: csv = request.files['csv'] csv.save('uploads/csvs/' + csv.filename)
The main reason of your problem lands here:
def validate(self): """Validate the form.""" initial_validation = super(UploadForm, self).validate() if not initial_validation: return False
so in validate
method of UploadForm
class.
Let's quick investigate what is happening here.
In views.py
in line:
if uploadform.validate_on_submit():
flask_wtf
package calls validate
method. So take a look again on your overwritten method:
def validate(self): """Validate the form.""" initial_validation = super(UploadForm, self).validate() if not initial_validation: return False
what is wrong here? In case initial_validation
would be True
, your validate
method will return None
. So what should happen? Only html rendering:
def upload(): uploadform = UploadForm() if uploadform.validate_on_submit(): # <--- here it's None filename = secure_filename(form.csv.data.filename) uploadform.csv.data.save('uploads/csvs/' + filename) flash("CSV saved.") return redirect(url_for('list')) else: # <--- so this block runs filename = None # And your app will only render the same view as when using HTTP GET on that method return render_template('spreadsheets/upload.html', uploadform=uploadform)
So if overwriting validate
method is not necessary, then just remove it, and if is, then adjust it to return True
:
def validate(self): """Validate the form.""" initial_validation = super(UploadForm, self).validate() if not initial_validation: return False return True # <-- this part is missing
Of course you can use shortened and I think more appropriate version:
def validate(self): """Validate the form.""" initial_validation = super(UploadForm, self).validate() return not initial_validation