Aller au contenu

Valider un upload

Objectif : comprendre pourquoi un fichier est refusé — la taxonomie des règles de validation.

Ce que vous allez apprendre : save_upload valide extension, type MIME et taille avant d'écrire. Chaque refus lève une exception précise de la hiérarchie UploadError (qui vit dans le core, réexportée par files). Ce palier nomme la règle qui rejette.

Premier palier du niveau intermédiaire de la progression files.

Module opt-in

Ce starter suppose forge-mvc-files installé (palier « Installation »).

Ce que ce starter montre

  • un formulaire d'upload (CSRF) ;
  • la capture des sous-types UploadInvalidExtensionError, UploadInvalidMimeTypeError, UploadTooLargeError ;
  • l'affichage de la règle qui a rejeté le fichier.

Classes Forge utilisées

Classe / fonction Rôle dans ce starter Référence
forge_mvc_files.save_upload Tente l'upload (valide puis écrit). Médias
UploadInvalidExtensionError / …MimeTypeError / UploadTooLargeError Refus précis selon la règle. Médias

Tester

forge run

Ouvrez https://localhost:8000/file-validate et tentez un .exe (extension), un fichier mal typé, ou un fichier trop gros : chaque refus nomme sa règle.

Le contrôleur

# mvc/controllers/file_validate_controller.py
from forge_mvc_files import (
    UploadError, UploadInvalidExtensionError,
    UploadInvalidMimeTypeError, UploadTooLargeError, save_upload,
)


class FileValidateController(BaseController):

    @staticmethod
    def check(request: Request) -> Response:
        uploaded = request.file("document")
        context = {"csrf_token": BaseController.csrf_token(request)}
        try:
            saved = save_upload(uploaded, "documents")
        except UploadInvalidExtensionError as exc:
            context["rejected"] = {"rule": "extension", "message": str(exc)}
        except UploadInvalidMimeTypeError as exc:
            context["rejected"] = {"rule": "type MIME", "message": str(exc)}
        except UploadTooLargeError as exc:
            context["rejected"] = {"rule": "taille", "message": str(exc)}
        except UploadError as exc:
            context["rejected"] = {"rule": "autre", "message": str(exc)}
        else:
            context["accepted"] = saved.original_name
        return BaseController.render("file_validate/index.html", context=context, request=request)

Comprendre ce code

  • La hiérarchie UploadError permet d'attraper du plus précis au plus général : on nomme la cause exacte, ou on retombe sur « autre ».
  • La validation est partagée (elle vit dans le core) : même politique pour files, images, et tout consommateur.

À retenir

  • Un refus d'upload a une cause précise (extension / MIME / taille).
  • La hiérarchie d'exceptions permet de la nommer à l'utilisateur.
  • Valider, c'est refuser avant d'écrire.

Après ce starter

Vous savez pourquoi un fichier est refusé. La suite : empêcher l'abus de la route.

Limiter les uploads