Flask-WTF FileField不会将数据属性设置为Werkzeug FileStorage的实例

时间:2013-10-05 22:23:39

标签: python python-2.7 flask wtforms flask-wtforms

Flask-WTF的documentation声明:

  

Flask-WTF为您提供了一个FileField来处理文件上传,如果表单已发布,它将自动从flask.request.files中提取数据。 FileField的data属性将是Werkzeug FileStorage的一个实例。

但是,当我使用FileField时,发布后的data属性不是FileStorage对象。相反,它是None(如果我使用文档中建议的enctype="multipart/form-data"定义我的表单)或文件名作为字符串(如果我没有定义enctype)。< / p>

以下是相关的Jinja2模板:

{% 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 %}

_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 %}

这是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)

enctype元素上的form属性,打印类型为NoneType;如果没有enctype属性,则打印类型为unicode。文档也没有宣传FileStorage对象。

2 个答案:

答案 0 :(得分:7)

我查看了源代码(form.py)并找出了问题:如果使用特定的{初始化表单,则不会激活使用FileStorage对象替换默认数据属性的代码{1}}。必须保留formdata未指定,才能使文件功能正常工作。替换这一行:

formdata

这一行:

form = SettingsForm(request.form)

解决了这个问题。

答案 1 :(得分:0)

清除传递的表单数据的替代方法
@import '~styles/config'; :global { @import '~styles/base'; } .layout { display: block; min-height: 100vh; } .pageEnter { display: none; } .fadeEffect { display: none; position: fixed; z-index: 9; top: 0; left: 0; width: 100%; height: 100%; background: #fff; transition: opacity 0.15s linear; &Enter { display: block; opacity: 0; } &Active, &Done, &Exit { display: block; opacity: 1; } &ExitActive { opacity: 0; } } form = SettingsForm(request.form)

应当按照flask-wtf documentation的建议同时传递form = SettingsForm() request.form

request.files