Aller au contenu principal

3 formations sont désormais disponibles : Python, Flask et JS.

Aller au contenu principal

Permettre aux utilisateurs d'envoyer des fichiers, c'est utile (avatar, documents...), mais c'est RISQUÉ. Imagine si quelqu'un upload un script Python malveillant à la place d'une image...

1. Le Formulaire

Il te faut un FileField et un validateur FileRequired. On peut aussi filtrer par extension avec FileAllowed.

from flask_wtf.file import FileField, FileRequired, FileAllowed

class PhotoForm(FlaskForm):
    photo = FileField('Photo de profil', validators=[
        FileRequired(),
        FileAllowed(['jpg', 'png'], 'Images seulement !')
    ])
    submit = SubmitField('Uploader')

2. Le Template

🚨 TRÈS IMPORTANT : La balise form doit avoir l'attribut enctype="multipart/form-data". Sinon, le fichier ne passera pas !

<form method="POST" enctype="multipart/form-data">
    {{ form.hidden_tag() }}
    {{ form.photo() }}
    {{ form.submit() }}
</form>

3. La Vue (Python)

On doit sécuriser le nom du fichier avec secure_filename. Pourquoi ? Si le gars nomme son fichier ../../../../etc/passwd, il pourrait essayer d'écraser des fichiers système. secure_filename nettoie tout ça.

import os
from werkzeug.utils import secure_filename

app.config['UPLOAD_FOLDER'] = 'static/uploads' # Dossier de destination

@app.route('/upload', methods=['GET', 'POST'])
def upload():
    form = PhotoForm()
    if form.validate_on_submit():
        f = form.photo.data
        filename = secure_filename(f.filename) # "Mon Photo.jpg" -> "Mon_Photo.jpg"
        
        # Sauvegarde
        f.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        
        flash('Image uploadée !')
        return redirect(url_for('index'))
        
    return render_template('upload.html', form=form)

Et voilà ! Tu sais maintenant gérer les entrées utilisateur de A à Z. Prochaine grosse étape : Stocker tout ça durablement dans une Base de Données. Prépare ton SQL (ou pas) !