Flask WTForms: Why is my POST request to upload a file not sending file data?


Katie

I'm trying to make a form that uploads a file, but the file data is not being sent with the request. I am manually navigating to my file and hitting submit. My FileRequired validator fails. (If I don't include, the datafield form.scan_fileis empty.)

Here is my form:

from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed, FileRequired

class ScanForm(FlaskForm):
    scan_file = FileField(validators=[FileAllowed(['nii', 'nii.gz', 'zip']), FileRequired()])

Here is mine views.py:

from flask import Blueprint, render_template, request, flash, redirect, url_for, session
from .models import Scan
from .forms import ScanForm
from .service import ScanService
from cookiecutter_mbam.utils import flash_errors

blueprint = Blueprint('scan', __name__, url_prefix='/scans', static_folder='../static')

@blueprint.route('/add', methods=['GET', 'POST'])
def add():
    """Add a scan."""
    form = ScanForm(request.form)
    if form.validate_on_submit():
        f = form.scan_file.data
        service = ScanService()
        xnat_uri = service.upload(session['user_id'], session['curr_experiment'], f)
        Scan.create(xnat_uri=xnat_uri)
        flash('You successfully added a new scan.', 'success')
        return redirect(url_for('experiment.experiments'))
    else:
        flash_errors(form)
    return render_template('scans/upload.html',scan_form=form)

Here is mine upload.html:

{% extends "layout.html" %}

{% block content %}


<form method="POST" action="{{ url_for('scan.add') }}" enctype="multipart/form-data">
    {{ scan_form.csrf_token }}

    <input type="file" name="file">
    <input class="btn btn-primary" type="submit" value="Submit">

</form>

{% endblock %}

It seems I made the same mistake as this guy . What am I doing wrong?

EDIT: I've found this question since posting , but while working through the solutions provided, none seem to be relevant to my situation.

Edit 2: At one point, I printed request.files in the Werkzeug debugger, which was an empty dictionary. I can't completely rebuild what I did to get that result. Since then, I've inserted some print statements and, in fact, request.fileshave my file object. So I have a way to retrieve my files. But I should be able to get back my file object form.scan_file.data(see here ). Now, this result is None. More specifically, it form.scan_file.has_file()is calculated as False. form.dataEvaluate as{'scan_file': None, 'csrf_token': <long-random-string> }

The result of this problem is that validation doesn't work, even though I have another method of retrieving the file object. My form doesn't pass FileRequired() validation.

EDIT 3: With a new understanding of the problem, I found that it is similar to this question . However, it's at least apparently not duplicated, since there isn't form = ScanForm(request.form), form = ScanForm()or form = ScanForm(CombinedMultiDict((request.files, request.form)))makes any difference in the behavior listed in Edit 2.

Dinko Pehar

First, check if your data is published on that route . Second, I don't think you need to pass request.formto ScanForm, just instantiate it:

def add():
    """Add a scan."""
    form = ScanForm()
    ...

To check for content posted via the form, instead of

if form.validate_on_submit():

You can use and print form.scan_file.data:

if form.is_submitted():
    print(form.scan_file.data)

Finally, you can render the input file using {{scan_form.scan_file}} or <input type="file" name="scan_file">(the name attribute of the input element should be equal to "scan_file" ) .

Here is my example:

form:

class ArticleForm(FlaskForm):
    article_image = FileField('Article_image', validators=[FileRequired()])

Form in template:

<form action="" method="post" enctype="multipart/form-data">
    {{ article_form.csrf_token }}
    {{ article_form.article_image }}
    <input type="submit" value="submit"/>
</form>

Controller (save file):

article_form = ArticleForm()

        if article_form.validate_on_submit():

            f = article_form.article_image.data
            name = current_user.username + "__" + f.filename
            name = secure_filename(name)
            f.save(os.path.join("./static/article_images/", name))

Related


Multipart data POST request to upload file

priority While integrating FreshDesk into my product, I got stuck with Create Ticket with Attachment API. I am using Advanced Rest Client to test an API. I've seen a lot of forums and questions on Stack Overflow itself, but I'm still not satisfied with any ans

Multipart data POST request to upload file

priority While integrating FreshDesk into my product, I got stuck with Create Ticket with Attachment API. I am using Advanced Rest Client to test an API. I've seen a lot of forums and questions on Stack Overflow itself, but I'm still not satisfied with any ans

Postman - POST request and upload file

Amit Cohen I'm testing an event flow and one of the steps is uploading a file, which is a RAR file. This step is done with a POST request, in the body you can add fields and give them a value, you can also select a file field, and on the right you can browse a

Flask-WTF file upload with wtforms fails validation

Deforsyth I'm trying to upload a file to a flask form but it fails validation. I've been following the documentation , and have tried the current approach and CombinedMultiDict()the process of submitting into the form, with no luck. I have printed out the erro

Flask-WTF file upload with wtforms fails validation

Deforsyth I'm trying to upload a file to a flask form but it fails validation. I've been following the documentation and have tried the current approach and CombinedMultiDict()the process of submitting into the form, but no luck. I have printed out the error.

Flask-WTF file upload with wtforms fails validation

Deforsyth I'm trying to upload a file to a flask form but it fails validation. I've been following the documentation and have tried the current approach and CombinedMultiDict()the process of submitting into the form, but no luck. I have printed out the error.

Get file size via upload and POST request

John Snow Please note: I want to do it using vanilla node. I want to upload a file with input type="file"HTML markup and click the submit button in the same form element input type="submit"and get the file size (in bytes) when a POST request is submitted. than

Is curl's --upload-file a post request?

Olddev I'm a little confused about curl's "--upload-file" parameter. The man page only states that it "transfers the specified local file to a remote URL". Is this a post request? If not, what is it? What would that look like in an actual HTML5 client applicat

Upload file with Volley custom body post request

iluxa.b I need to send 2 files to a server using the volley library in Android. There is an example of how it works well in Postman: I need to reproduce this POST call exactly in android. Now please take a look at my code (it doesn't work): JsonObjectRequest s

Upload file to Django using request.post()

Meat mountain I'm pretty new to django and I just can't figure out a way to upload a simple html file to django using request.post(). I tried the steps given in this https://blog.vivekshukla.xyz/uploading-file-using-api-django-rest-framework/ but when I give i

Upload file to Django using request.post()

Meat mountain I'm pretty new to django and I just can't figure out a way to upload a simple html file to django using request.post(). I tried the steps given in this https://blog.vivekshukla.xyz/uploading-file-using-api-django-rest-framework/ but when I give i

Upload file to Django using request.post()

Meat mountain I'm pretty new to django and I just can't figure out a way to upload a simple html file to django using request.post(). I tried the steps given in this https://blog.vivekshukla.xyz/uploading-file-using-api-django-rest-framework/ but when I give i

Upload file via POST request without HttpClient

dropper As far as I know it HttpClientis deprecated since Android API 22 . That's why I don't want to use it. I need to upload files to view requests and possibly track upload progress. Is there a way?POST Platt You can use HttpUrlConnection with Asyctask to s

Django: upload file via POST request

Pavel Shishmarev I'm trying to upload a file via APIView, but I'm getting an exception: {"exception": "ValidationException", "code": 401, "message": "You cannot access body after reading from request's data stream"}this is my code: API view: class SetAvatarVie

Get file size via upload and POST request

John Snow Please note: I want to do it using vanilla node. I want to upload a file with input type="file"HTML markup and click the submit button in the same form element input type="submit"and get the file size (in bytes) when a POST request is submitted. than

Upload file with Volley custom body post request

iluxa.b I need to send 2 files to a server using the volley library in Android. There is an example of how it works well in Postman: I need to reproduce this POST call exactly in android. Now please take a look at my code (it doesn't work): JsonObjectRequest s