1. get_valid_filename qu'est-ce que c'est ?



django.utils.text.get_valid_filename est une petite fonction utilitaire qui transforme une chaîne en un nom de fichier sécuritaire pour le système de fichiers.
Elle supprime ou change les caractères interdits (slash, caractères de contrôle, etc.) présents sur la plupart des systèmes d'exploitation comme Windows, macOS et Linux, et normalise la chaîne dans un format prévisible.

Pourquoi est-ce nécessaire ?
Lorsque l'utilisateur télécharge un fichier ou crée un nom de fichier à partir d'une entrée arbitraire (par exemple, un titre de blog, des tags utilisateur), les traversées de répertoires, comme le caractère slash (../etc/passwd), ou des caractères anormaux peuvent endommager le système de fichiers ou créer des vulnérabilités de sécurité.


2. Fonctionnement

from django.utils.text import get_valid_filename

raw = "My: New/Project? 2024*"
safe = get_valid_filename(raw)
print(safe)   # → "My_New_Project_2024"

Comportement principal

Entrée Résultat Description
"my file.txt" "my_file.txt" Espaces → tirets bas
"../etc/passwd" "etc_passwd" Supprime les points et slash au début
"file<name>.txt" "file_name_.txt" Les caractères < et > sont changés
" " "" Si seulement des espaces, retourne une chaîne vide
"a"*300 "a"*255 Coupe à la limite du système de fichiers (255 caractères)

La fonction est multi-plateforme et n'autorise qu'un ensemble de caractères sûrs ([A-Za-z0-9_.-]), remplaçant les autres par un tiret bas (_).


3. Situations utiles



Situation Nécessité
Téléchargement d'utilisateur Prévenir les traversées de répertoire (../../etc/passwd) et les caractères interdits
Noms de fichiers basés sur des slugs Transformer un titre de blog en nom de fichier pour un site statique
Exportation de données Générer des noms de fichiers CSV/JSON incorporant des champs de base de données (virgules, guillemets, etc.)
Sauvegarde automatique Créer des noms de fichiers de sauvegarde avec des timestamps à partir de chaînes aléatoires

4. Exemple pratique : stockage d'upload d'image

# views.py
from django.shortcuts import render
from django.core.files.storage import default_storage
from django.utils.text import get_valid_filename

def upload_image(request):
    if request.method == 'POST':
        uploaded = request.FILES['image']
        # Nettoyage du nom de fichier d'origine
        safe_name = get_valid_filename(uploaded.name)
        # Ajouter l'ID utilisateur ou un timestamp si nécessaire
        final_name = f"{request.user.id}_{safe_name}"
        path = default_storage.save(f"uploads/{final_name}", uploaded)
        return render(request, 'success.html', {'path': path})
    return render(request, 'upload.html')

Résultat
Peu importe comment l'utilisateur nomme le fichier, le nom enregistré sera sûr, sans traversées de répertoire, et avec un faible risque de duplication.


5. Références rapides

from django.utils.text import get_valid_filename

# 1. Nettoyage de base
safe = get_valid_filename("My: New/Project? 2024*")  # → "My_New_Project_2024"

# 2. Utilisation dans un chemin de fichier
path = f"media/{safe}.jpg"

# 3. Association avec UUID pour garantir l'unicité
import uuid
unique_name = f"{uuid.uuid4().hex}_{safe}.jpg"

6. Résumé clé

  • get_valid_filename protège le système de fichiers des noms dangereux par une ligne de code.
  • Utilisez-le chaque fois que vous transformez des entrées utilisateur ou des chaînes arbitraires en noms de fichiers.
  • Le code est propre, multi-plateforme et sécurisé.

Conseil : Si vous devez conserver les espaces ou préserver Unicode, vous pouvez combiner avec slugify ou créer un helper personnalisé, mais dans la plupart des cas, get_valid_filename est le plus adapté.