List and serve files from GridFS with Flask

自闭症网瘾萝莉.ら 提交于 2021-02-07 04:33:21

问题


I have files stored in GridFS. I want to show the user a list of files, and allow them to download them. I have the following code that saves the file to the server, but I'm not sure how to serve the file to the client. How do I serve files from GridFS with Flask?

<form id="submitIt" action="/GetFile" method="Post">
{% for file in List %}
<input type="checkbox" name="FileName" value={{file.strip('u').strip("'")}}>{{file.strip('u').strip("'")}}<br>
{% endfor %}
<a href="#" onclick="document.getElementById('submitIt').submit();">Download</a>
</form>
@app.route('/GetFile',methods=['POST'])
def GetFile():
    connection = MongoClient()
    db=connection.CINEfs_example
    fs = gridfs.GridFS(db)
    if request.method == 'POST': 
        FileName=request.form.getlist('FileName')
        for filename in FileName:
            EachFile=fs.get_last_version(filename).read()
            with open(filename,'wb') as file2:
                file2.write(EachFile)
    return 'files downloaded'

回答1:


Rather than saving the file retrieved from GridFS to the server's filesystem, pass it on to the client in response. You cannot send more than one file at once, so you'll have to remove the ability to select multiple files. You don't need a form at all, just pass the name in the url and create a list of links in the template.

@app.route('/get-file/<name>')
@app.route('/get-file')
def get_file(name=None):
    fs = gridfs.GridFS(MongoClient().CINEfs_example)

    if name is not None:
        f = fs.get_last_version(name)
        r = app.response_class(f, direct_passthrough=True, mimetype='application/octet-stream')
        r.headers.set('Content-Disposition', 'attachment', filename=name)
        return r

    return render_template('get_file.html', names=fs.list())

get_file.html:

<ul>{% for name in names %}
<li><a href="{{ url_for('get_file', name=name) }}">{{ name }}</a></li>
{% endfor %}</ul>



回答2:


To serve file to client, you can prepare a view similar to this:

@app.route('/client/serve/<file_id>/', methods=['GET', 'POST'])
@login_required
def serve_file(file_id):
    from mongoengine.connection import get_db
    from gridfs import GridFS, NoFile
    from bson.objectid import ObjectId
    from flask import make_response

    db = get_db()
    fs = GridFS(db)
    try:
        f = fs.get(ObjectId(file_id))
    except NoFile:
        fs = GridFS(db, collection='images')  # mongoengine stores images in a separate collection by default
        try:
            f = fs.get(ObjectId(file_id))
        except NoFile:
            raise ValueError("File not found!")

    response = make_response(f.read())
    response.mimetype = 'image/jpeg'
    return response


来源:https://stackoverflow.com/questions/32492501/list-and-serve-files-from-gridfs-with-flask

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!