关于flask的FileStorage对象的读取问题

对于通过设置form表单POST方法进入的文件对象,flask创建了一个FileStorage对象进行存储

该对象可以直接被用来put到mongodb中的GridFs

# class attachment(db.Document)
attachment.file.put(f, filename=f.filename)

也可以存储到本地

# 文件存储路径 target
target = "/".join([target, filename])
f.save(target)

但是每次被put之后,再进行存储本地时就会导致存储到本地的文件length为0

查找了一下存储原理,FileStorage存储后会read到end,所以第二次进行存储的时候,文件已经无法继续read

解决方法是:

在第一次put之后

f.stream.seek(0)

 其实后面了解GridFS之后,其实不太需要再保存到本地

如何使用GridFs存储文件,可以自行baidu

举个demo

@edit.route('/upattachment/<string:a_id>', methods=['POST'])
def upattachment(a_id):
    # get article
    article = Article.objects.get_or_404(id=ObjectId(a_id))
    f = request.files['file']
    attachment = Attachment(origin_filename=f.filename, extension=os.path.splitext(f.filename)[1])
    attachment.file.put(f, filename=f.filename)
    article.attachments.append(attachment)
    article.save()
    return jsonify({"filename": f.filename, "stat": "success"})


@edit.route('/downattachment')
def download_attachment():
    # get args
    filename = request.args.get('filename')
    a_id = request.args.get('aid')
    article = Article.objects.get_or_404(id=ObjectId(a_id))
    attachment = article.find_attachments(filename)[0]

    def gen_mongo(file):
        # file is mongodb.FileField.file
        while 1:
            chunk = file.read(256 * 1024)
            if not chunk:
                break
            yield chunk

    response = Response(gen_mongo(attachment.file), content_type='application/octet-stream')
    response.headers['Content-disposition'] = 'attachment;filename=%s' % filename
    response.content_length = attachment.file.length
    return response

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值