问题
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