Flask FileStorage保存空文件

时间:2019-01-02 21:38:54

标签: python flask flask-wtforms wtforms file-storage

我正在与Flask,WTForms和Flask-WTF一起保存文件,但是该文件始终存储为空文件。它没有显示任何错误。

表格:

lynx "$HTMLFILE"

瓶径/功能:

from flask_wtf import FlaskForm
from flask_wtf.file import FileField
from wtforms import StringField, SubmitField

class UserForm(FlaskForm):
    username = StringField('u', validators=[InputRequired()])
    email = StringField('e', validators=[InputRequired()])
    password = StringField('c', validators=[InputRequired()])
    signature = FileField('s')
    save = SubmitField('a')

HTML

@bp.route('/manage/user', methods=['GET', 'POST'])
@login_required
def manage_user():
    form = UserForm()
    action = 'create'

    try:        
        if form.validate_on_submit():
            if form.save.data:
                print('request.method', request.method)
                print('request.args', request.args)
                print('request.form', request.form)
                print('request.files', request.files)
                # archivo = request.files['signature']
                # archivo = request.files.items()[0]
                archivo = form.signature.data
                print(type(archivo))
                if archivo:
                    image_data = archivo.read()
                    basedir = os.path.abspath(os.path.dirname(__file__))
                    filename = secure_filename(form.username.data+'.png')
                    full_dir = os.path.join(basedir, '..\\static\\img', filename)
                    print(sys.getsizeof(archivo))
                    archivo.save(full_dir) 
                return redirect(url_for('main.manage'))
    except Exception as e:
        print(e)

    return render_template('manage_user.html', title=('Admon'), form=form, action=action)

打印语句显示以下内容: Print results

打印顺序为:

  1. 请求方法
  2. 请求参数
  3. 请求表
  4. 请求文件
  5. archivo变量的类型

archivo的大小始终为32,与我上传的图像无关,始终为32,因此从这一点来看已经是空的,还没有弄清楚为什么会变空。我正在关注这些示例。

https://flask-wtf.readthedocs.io/en/latest/form.html

2 个答案:

答案 0 :(得分:2)

首先,文件的大小始终为32,因为sys.getsizeof()返回Python用于该对象的内存量,如docs中所述。

要打印实际文件大小,可以使用:

os.path.getsize('path')

使用它,您应该看到打印的文件大小实际上是0。

其次,通过删除:

image_data = archivio.read()

您应该能够成功将文件保存在所需位置。

我不确定您要使用archivio.read()完成什么。

答案 1 :(得分:0)

对于刚刚偶然发现此问题的任何人,

当您对同一个文件对象执行 save() 和 read() 时会发生此错误。

我通过检查 2 个场景扩展了我的研究:

1.read() before save()

read() 函数将读取文件并将光标置于文件末尾。如果这个对象现在被保存,它将是空的。

2.在读取()之前保存()

成功保存()文件后,文件对象变为空。如果你现在尝试阅读它,你会得到一个空字符串 ''

3. Deepcopy这个文件对象,以便对单独的文件对象执行read()和save()

不允许。某些文件类型(例如 FileStorage)无法进行深度复制。参考this answer

解决方法

根据 Naisarg 在此 answer 中的评论:

  1. 在后台保存文件。

    file = request.files['file']

    file.save(secure_filename(file.filename))

  2. 阅读该文件。

  3. 将该文件附加到第 3 方 API。

    r = requests.post(url, headers=headers, data=payload, files={'file': (file.filename, open(file.filename, 'rb'), file.content_type)})

  4. 在后台删除文件。

    os.remove(file.filename)