web-dev-qa-db-fra.com

Flask Télécharger un fichier

J'essaie de créer une application Web avec Flask qui permet à un utilisateur de télécharger un fichier et de le transmettre à un autre utilisateur. Pour le moment, je peux télécharger le fichier sur le upload_folder correctement, mais je n'arrive pas à trouver le moyen de permettre à l'utilisateur de le télécharger à nouveau.

Je stocke le nom du nom de fichier dans une base de données.

J'ai une vue servant les objets de base de données. Je peux les supprimer aussi.

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

Dans mon HTML j'ai:

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

et une vue de téléchargement:

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

Mais ça revient:

Pas trouvé

L'URL demandée n'a pas été trouvée sur le serveur. Si vous avez entré l'URL manuellement, vérifiez votre orthographe et réessayez.

Je veux juste lier le nom de fichier à l'objet et laisser l'utilisateur le télécharger (pour chaque objet de la même vue)

35
Saimu

Vous devez vous assurer que la valeur que vous transmettez à l'argument directory est un chemin absolu, corrigé pour l'emplacement actuel de votre application.

La meilleure façon de faire est de configurer UPLOAD_FOLDER en tant que chemin relatif (pas de barre oblique), puis définissez-le en absolu en préfixant 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)

Il est important de rappeler que UPLOAD_FOLDER doit être relatif pour que cela fonctionne, par exemple ne commence pas par un /.

Un chemin relatif pourrait fonctionne, mais repose trop sur le répertoire de travail actuel étant défini à l'emplacement où votre code Flask) est présent. Ce n'est peut-être pas toujours le cas.

42
Martijn Pieters

Pour télécharger le fichier sur flask call. Le nom du fichier est Examples.pdf Quand je frappe 127.0.0.1:5000/ télécharger il devrait être téléchargé.

Exemple:

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 __== '__main__':
    app.run(port=5000,debug=True) 
7
Viraj.Hadoop

Je développais également une application similaire. J'obtenais également erreur non trouvée même si le fichier était là. Cela résout mon problème. Je mentionne mon dossier de téléchargement dans 'static_folder':

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

Mon code pour le téléchargement est le suivant:

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

Voici comment j'appelle mon fichier depuis 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>
3
Waqar Detho