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_filename protege 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 slugify o crear una función auxiliar personalizada, pero en la mayoría de los casos get_valid_filename es la opción más adecuada.