【问题标题】:Flask-WTF FileField does not set data attribute to an instance of Werkzeug FileStorageFlask-WTF FileField 没有将数据属性设置为 Werkzeug FileStorage 的实例
【发布时间】:2013-10-12 18:10:57
【问题描述】:

Flask-WTF 的 documentation 声明:

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

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

这里是相关的 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)

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

【问题讨论】:

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


    【解决方案1】:

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

    form = SettingsForm(request.form)
    

    用这一行:

    form = SettingsForm()
    

    解决了问题。

    【讨论】:

    • 您好,感谢您的回答。我在 form.py 的源代码中找不到您所指的位置。你有更多细节吗?
    • @KevinLEGOFF 不是 OP,但我相信他们在谈论 this part
    • 感谢您的回答,这个问题快把我逼疯了
    【解决方案2】:

    清除传递的表单数据的替代方法
    form = SettingsForm(request.form)form = SettingsForm()

    是通过request.form request.files 正如flask-wtf documentation 所建议的那样。

    from flask import request
    from werkzeug.datastructures import CombinedMultiDict
    
    form = SettingsForm(CombinedMultiDict((request.files, request.form)))
    

    【讨论】:

      猜你喜欢
      • 2020-01-02
      • 1970-01-01
      • 2016-08-24
      • 2018-03-15
      • 1970-01-01
      • 2013-01-13
      • 1970-01-01
      • 2015-06-12
      • 1970-01-01
      相关资源
      最近更新 更多