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_filenameprotè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
slugifyou créer un helper personnalisé, mais dans la plupart des cas,get_valid_filenameest le plus adapté.
Aucun commentaire.