【问题标题】:Flask Download a File烧瓶下载文件
【发布时间】:2014-08-25 23:21:28
【问题描述】:

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

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

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

@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)

在我的 HTML 中,我有:

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

和下载视图:

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

但它正在返回:

找不到

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

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

【问题讨论】:

  • Flask 对于​​什么 URL 会返回 404 Not Found 响应?您是否验证了相关文件名确实位于 app.config['UPLOAD_FOLDER'] 中?
  • 确实如此,因为我有一个确实上传文件的上传表单。我就是不能下载。上传到文件夹没问题。网址是:127.0.0.1:5000/uploads/rsc_chapitre17.pdf,文件确实存在!
  • 我问的原因是因为send_from_directory() 会在没有文件时引发NotFound。所以os.path.isfile(app.config['UPLOAD_FOLDER']/filename) 返回了错误。您需要仔细检查 UPLOAD_FOLDER 的内容并确认您尝试加载的文件名真的在那里。
  • 它在那里,将 app = Flask(name) 更改为 app = Flask(name, static_folder='uploads') 并且出于某些原因它奏效了。
  • Python 可以很好地处理斜杠。 前导斜线是这里的问题。您定义了绝对路径,而不是相对路径。

标签: python flask download flask-sqlalchemy


【解决方案1】:

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

最好的方法是将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)

重申UPLOAD_FOLDER 必须是相对的才能起作用,例如不要以/开头。

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

【讨论】:

    【解决方案2】:

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

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

    我的下载代码如下:

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

    这就是我从 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>
    

    【讨论】:

    • 你不需要甚至想要设置static_folder来指向你的pdf子目录。这只是意味着/static/ 路径中的所有内容也 由pdf sub 文件夹提供。正如我在回答中所说:相对路径可以工作,但过于依赖当前工作目录设置为您的 Flask 代码所在的位置。;你在directory='pdf' 中的相对路径也会落入那个陷阱。
    【解决方案3】:

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

    例子:

    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) 
    

    【讨论】:

    • 这实际上并没有解决问题,它使用可变路径元素来命名要下载的文件。
    • 没关系。具有高 SEO 排名 + 总标题 Flask Download a File 的问题应该更普遍地回答 IMO
    【解决方案4】:
    #HTML Code
     
    <ul>
     {% for file in files %}
      <li> <a href="{{ url_for('download', filename=file) }}">{{ file }}</a></li>
     {% endfor %}
    </ul>
    
    
    #Python Code
    
    from flask import send_from_directory
    
    app.config['UPLOAD_FOLDER']='logs'
    
    
    @app.route('/uploads/<path:filename>', methods=['GET', 'POST'])
    def download(filename):
        print(app.root_path)
        full_path = os.path.join(app.root_path, app.config['UPLOAD_FOLDER'])
        print(full_path)
        return send_from_directory(full_path, filename)
    
    

    【讨论】:

      猜你喜欢
      • 2021-07-15
      • 1970-01-01
      • 1970-01-01
      • 2021-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-27
      相关资源
      最近更新 更多