File not uploading with Flask-wtforms in cookiecutter-flask app File not uploading with Flask-wtforms in cookiecutter-flask app flask flask

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