Python Flask 下载文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24577349/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 04:48:46  来源:igfitidea点击:

Flask Download a File

pythonflaskdownloadflask-sqlalchemy

提问by Saimu

I'm trying to create a web app with Flask that lets a user upload a file and serve them to another user. Right now, I can upload the file to the upload_foldercorrectly. But I can't seem to find a way to let the user download it back.

我正在尝试使用 Flask 创建一个网络应用程序,让用户上传文件并将其提供给另一个用户。现在,我可以将文件正确上传到upload_folder。但我似乎找不到让用户下载回来的方法。

I'm storing the name of the filename into a database.

我正在将文件名的名称存储到数据库中。

I have a view serving the database objects. I can delete them too.

我有一个服务于数据库对象的视图。我也可以删除它们。

@app.route('/dashboard', methods=['GET', 'POST'])
def dashboard():

    problemes = Probleme.query.all()

    if 'user' not in session:
        return redirect(url_for('login'))

    if request.method == 'POST':
        delete = Probleme.query.filter_by(id=request.form['del_button']).first()
        db.session.delete(delete)
        db.session.commit()
        return redirect(url_for('dashboard'))

    return render_template('dashboard.html', problemes=problemes)

In my HTML I have:

在我的 HTML 中,我有:

<td><a href="{{ url_for('download', filename=probleme.facture) }}">Facture</a></td>

and a download view :

和下载视图:

@app.route('/uploads/<path:filename>', methods=['GET', 'POST'])
def download(filename):
    return send_from_directory(directory=app.config['UPLOAD_FOLDER'], filename=filename)

But it's returning :

但它回来了:

Not Found

未找到

The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.

在服务器上找不到请求的 URL。如果您手动输入了 URL,请检查您的拼写并重试。

I just want to link the filename to the object and let the user download it (For every object in the same view)

我只想将文件名链接到对象并让用户下载它(对于同一视图中的每个对象)

采纳答案by Martijn Pieters

You need to make sure that the value you pass to the directoryargument is an absolute path, corrected for the currentlocation of your application.

您需要确保传递给directory参数的值是绝对路径,并针对应用程序的当前位置进行了更正。

The best way to do this is to configure UPLOAD_FOLDERas a relative path (no leading slash), then make it absolute by prepending current_app.root_path:

最好的方法是配置UPLOAD_FOLDER为相对路径(没有前导斜杠),然后通过添加绝对路径current_app.root_path

@app.route('/uploads/<path:filename>', methods=['GET', 'POST'])
def download(filename):
    uploads = os.path.join(current_app.root_path, app.config['UPLOAD_FOLDER'])
    return send_from_directory(directory=uploads, filename=filename)

It is important to reiterate that UPLOAD_FOLDERmust be relative for this to work, e.g. not start with a /.

重要的是要重申,UPLOAD_FOLDER必须是相对的才能使其工作,例如不要以/.

A relative path couldwork but relies too much on the current working directory being set to the place where your Flask code lives. This may not always be the case.

相对路径可以工作,但过于依赖当前工作目录设置为您的 Flask 代码所在的位置。情况可能并非总是如此。

回答by Waqar Detho

I was also developing a similar application. I was also getting not found error even though the file was there. This solve my problem. I mention my download folder in 'static_folder':

我也在开发一个类似的应用程序。即使文件在那里,我也没有找到错误。这解决了我的问题。我在“static_folder”中提到了我的下载文件夹:

app = Flask(__name__,static_folder='pdf')

My code for the download is as follows:

我的下载代码如下:

@app.route('/pdf/<path:filename>', methods=['GET', 'POST'])
def download(filename):    
    return send_from_directory(directory='pdf', filename=filename)

This is how I am calling my file from html.

这就是我从 html 调用我的文件的方式。

<a class="label label-primary" href=/pdf/{{  post.hashVal }}.pdf target="_blank"  style="margin-right: 5px;">Download pdf </a>
<a class="label label-primary" href=/pdf/{{  post.hashVal }}.png target="_blank"  style="margin-right: 5px;">Download png </a>

回答by Viraj Wadate

To download file on flask call.File name is Examples.pdfWhen I am hitting 127.0.0.1:5000/downloadit should get download.

在烧瓶调用上下载文件。文件名是Examples.pdf当我点击127.0.0.1:5000/download它应该得到下载。

Example:

例子:

from flask import Flask
from flask import send_file
app = Flask(__name__)

@app.route('/download')
def downloadFile ():
    #For windows you need to use drive name [ex: F:/Example.pdf]
    path = "/Examples.pdf"
    return send_file(path, as_attachment=True)

if __name__ == '__main__':
    app.run(port=5000,debug=True)