Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MultipleFileField wtforms

class AddProductForm(FlaskForm):
    product_pictures = MultipleFileField('Pictures')
    submit = SubmitField('Add Pictures')

    def product_add_pics():
        form = AddProductForm()
        if form.validate_on_submit():
            if form.product_pictures.data:
                for picture_upload in form.product_pictures.data:
                    print(type(picture_upload))

form:

<div class="form-group">
    {{ form.product_pictures.label() }}
    {{ form.product_pictures(class="form-control-file") }}
    {% if form.product_pictures.errors %}
        {% for error in form.product_pictures.errors %}
            <span class="text-danger">{{ error }}</span>
        {% endfor %}
    {% endif %}
</div>

I always got type as string. How can I get the binary files? I use MultipleFileField from the wtforms.

like image 396
anhianhi Avatar asked Oct 27 '18 11:10

anhianhi


People also ask

What does WTForms stand for?

WTForms is a flexible forms validation and rendering library for Python web development. It can work with whatever web framework and template engine you choose. It supports data validation, CSRF protection, internationalization (I18N), and more.

Should I use WTForms?

WTForms are really useful it does a lot of heavy lifting for you when it comes to data validation on top of the CSRF protection . Another useful thing is the use combined with Jinja2 where you need to write less code to render the form. Note: Jinja2 is one of the most used template engines for Python.

What is Stringfield?

String field theory (SFT) is a formalism in string theory in which the dynamics of relativistic strings is reformulated in the language of quantum field theory.


2 Answers

The documentation for the FileField class specifically says the following about handling file contents:

By default, the value will be the filename sent in the form data. WTForms does not deal with frameworks’ file handling capabilities.

This same thing applies to the MultipleFileField class as well.

What this means is that you will have to ask flask for those files. And, the quickest way to do that is to use the request.files for the request you are handling.

In sum, you will need to rewrite your product_add_pics function to grab the files from the request object, as follows:

from flask import request



def product_add_pics():
    form = AddProductForm()
    if form.validate_on_submit():
        pics = request.files.getlist(form.product_pictures.name)
        if pics:
            for picture_upload in pics:
                picture_contents = picture_upload.stream.read()
                print(type(picture_contents))
                # Do everything else you wish to do with the contents

You'll notice the usage of request.files.getlist here. This is important since you're using a MultipleFielField class to accept multiple files. Using .getlist allows you to retrieve all the files the end user selected from their machine.

And finally, to get the bytes contained in each file, you will need to get the stream of each file and read it. That should yield the bytes you're looking for.

I hope this proves useful.

like image 88
Abdou Avatar answered Oct 13 '22 04:10

Abdou


I know this question is old but I spent four hours banging my head against the wall trying to find a solution and finally figured it out with the help of an error code. MultiFileField will return the filenames as a string unless you specify the proper encoding in your form. simply add:

enctype="multipart/form-data"

to the HTML form tag and the original code will return

<class 'werkzeug.datastructures.FileStorage'>

as expected.

like image 33
Shibarak Avatar answered Oct 13 '22 04:10

Shibarak