1. get_valid_filename ¿qué es?
django.utils.text.get_valid_filename es una pequeña función auxiliar que convierte cadenas en nombres de archivo seguros para el sistema de archivos.
Elimina o reemplaza caracteres problemáticos (como barras, caracteres de control, etc.) en la mayoría de los sistemas operativos como Windows, macOS y Linux, y normaliza la cadena en un formato predecible.
¿Por qué es necesario?
Cuando los usuarios suben archivos o crean nombres de archivo con entradas arbitrarias (por ejemplo, títulos de blogs, etiquetas de usuario), si incluyen caracteres inusuales o direcciones de directorio como (../etc/passwd), esto puede provocar un deterioro del sistema de archivos o vulnerabilidades de seguridad.
2. ¿Funcionamiento?
from django.utils.text import get_valid_filename
raw = "My: New/Project? 2024*"
safe = get_valid_filename(raw)
print(safe) # → "My_New_Project_2024"
Funcionamiento principal
| Entrada | Resultado | Descripción |
|---|---|---|
"my file.txt" |
"my_file.txt" |
Espacio → guion bajo |
"../etc/passwd" |
"etc_passwd" |
Eliminación de puntos y barras iniciales |
"file<name>.txt" |
"file_name_.txt" |
Reemplazo de <·> |
" " |
"" |
Cadenas vacías si solo hay espacios |
"a"*300 |
"a"*255 |
Recorta al límite del sistema de archivos (255 caracteres) |
La función es multiplataforma, permitiendo solo un conjunto seguro de caracteres ([A-Za-z0-9_.-]) y reemplazando el resto por guiones bajos (_).
3. Situaciones útiles
| Situación | Necesidad |
|---|---|
| Subidas de usuario | Prevenir el acceso a directorios (../../etc/passwd) y caracteres prohibidos |
| Nombres de archivo basados en slugs | Convertir títulos de blogs en nombres de archivo para sitios estáticos |
| Exportación de datos | Generar nombres de archivo CSV/JSON que contengan campos de base de datos (comas, comillas, etc.) |
| Copias de seguridad automáticas | Generar nombres de archivo de copia de seguridad con marcas de tiempo a partir de cadenas arbitrarias |
4. Ejemplo práctico: Almacenamiento de imágenes subidas
# 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']
# Organizar el nombre del archivo original
safe_name = get_valid_filename(uploaded.name)
# Agregar ID de usuario o marca de tiempo si es necesario
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')
Resultado
Independientemente de cómo el usuario especifique el nombre del archivo, el nombre guardado será seguro, sin acceso a directorios, y con una baja probabilidad de duplicados.
5. Referencia rápida
from django.utils.text import get_valid_filename
# 1. Organización básica
safe = get_valid_filename("My: New/Project? 2024*") # → "My_New_Project_2024"
# 2. Usado en rutas de archivo
path = f"media/{safe}.jpg"
# 3. Combinado con UUID para asegurar unicidad
import uuid
unique_name = f"{uuid.uuid4().hex}_{safe}.jpg"
6. Resumen clave
get_valid_filenameprotege el sistema de archivos de nombres peligrosos con una línea de código.- Úselo cada vez que convierta entrada de usuario o cadenas arbitrarias en nombres de archivo.
- El código es limpio, multiplataforma y seguro.
Consejo: Si necesita conservar espacios o caracteres Unicode, puede combinarlo con
slugifyo crear una función auxiliar personalizada, pero en la mayoría de los casosget_valid_filenamees la opción más adecuada.
No hay comentarios.