Flask-WTF FileField does not set data attribute in Werkzeug FileStorage instance

The Flask-WTF documentation says:

Flask-WTF provides you with a FileField for handling file uploads; it automatically outputs data from flask.request.files if the form is submitted. The FileField data attribute will be an instance of Werkzeug FileStorage.

However, when I use FileField , the data attribute after publishing is not a FileStorage object. Instead, it is either None (if I define my form using enctype="multipart/form-data" , as suggested in the documentation), or the file name as a string (if I do not define enctype ).

Here is the corresponding Jinja2 template:

 {% from "_form.html" import render_field %} {% block body %} <section class="page-width-container" id="offset-content"> <div id="utility-box"> <h1 class="utility-header">Settings</h1> {{ message }} <form action="/settings" method="post" enctype="multipart/form-data"> {{ render_field(form.photo) }} <input type="submit" class="form-action" value="Save" /> </form> </div> </section> {% endblock %} 

Macro _form.html:

 {% macro render_field(field) %} <div class="field"> {{ field.label }} <span class="form-input">{{ field()|safe }}</span> <div class="clear"></div> {% if field.errors %} <ul class="errors"> {% for error in field.errors %} <li>{{ error }}</li> {% endfor %} </ul> {% endif %} </div> {% endmacro %} 

And here is Python:

 from flask import Blueprint, render_template, request from flask.ext.wtf import Form from flask.ext.wtf.file import FileField, FileRequired settings_bp = Blueprint('settings', __name__) class SettingsForm(Form): photo = FileField('Photo', validators=[ FileRequired('no file!'), ]) @settings_bp.route('/settings', methods=['GET', 'POST']) def login(): form = SettingsForm(request.form) form.validate_on_submit() print(type(form.photo.data)) return render_template('settings.html', form=form, message=form.photo.data) 

With the enctype attribute in the form element, the printed type is NoneType ; without the enctype attribute enctype printed unicode type. A FileStorage object advertised by documentation.

+6
source share
1 answer

I looked at the source code ( form.py ) and found out the problem: the code replacing the default data attribute with a FileStorage object is not activated if the form is initialized with a specific formdata . In order for the functionality of the file to work, you must leave formdata unspecified. Replacing this line:

 form = SettingsForm(request.form) 

Using this line:

 form = SettingsForm() 

The issue is fixed.

+5
source

Source: https://habr.com/ru/post/955323/


All Articles