1. get_valid_filename — это что?
django.utils.text.get_valid_filename — это небольшая вспомогательная функция, которая превращает строки в безопасные для файловой системы имена файлов.
Она удаляет или заменяет запрещенные или проблемные символы (такие как слэши, управляющие символы и т. д.) в большинстве операционных систем, таких как Windows, macOS, Linux и нормализует строку в предсказуемый формат.
Зачем это нужно?
Когда пользователи загружают файлы или создают имена файлов из произвольного ввода (например, заголовок блога, теги пользователя), использование таких символов, как слэши (../etc/passwd), может привести к разрыву файловой системы или возникновению уязвимостей безопасности.
2. Как это работает
from django.utils.text import get_valid_filename
raw = "My: New/Project? 2024*"
safe = get_valid_filename(raw)
print(safe) # → "My_New_Project_2024"
Основные действия
| Ввод | Результат | Описание |
|---|---|---|
"my file.txt" |
"my_file.txt" |
Пробел → подчеркивание |
"../etc/passwd" |
"etc_passwd" |
Удален ведущий символ и слэш |
"file<name>.txt" |
"file_name_.txt" |
Символы < и > заменены |
" " |
"" |
Только пробелы приводят к пустой строке |
"a"*300 |
"a"*255 |
Обрезка до предела файловой системы (255 символов) |
Функция кроссплатформенная и допускает только безопасный набор символов ([A-Za-z0-9_.-]), остальные символы заменяются подчеркиванием (_).
3. Полезные ситуации
| Ситуация | Необходимость |
|---|---|
| Загрузка пользователем | Предотвращение обхода директорий (../../etc/passwd) и запрещенных символов |
| Имена файлов на основе слогов | Преобразование заголовка блога в имя файла для статического сайта |
| Экспорт данных | Создание имен файлов CSV/JSON с учетом полей базы данных (запятые, кавычки и др.) |
| Автоматическое резервное копирование | Создание имен файлов резервного копирования с временными отметками на основе произвольной строки |
4. Практический пример: Сохранение загруженных изображений
# 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']
# Очистка оригинального имени файла
safe_name = get_valid_filename(uploaded.name)
# При необходимости добавьте ID пользователя или временную метку
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')
Результат
Независимо от того, как пользователь задает имя файла, сохраняемое имя будет безопасным, без обхода директорий и с низкой вероятностью дублирования.
5. Быстрая справка
from django.utils.text import get_valid_filename
# 1. Основное очищение
safe = get_valid_filename("My: New/Project? 2024*") # → "My_New_Project_2024"
# 2. Используйте в именах файлов
path = f"media/{safe}.jpg"
# 3. Объедините с UUID для обеспечения уникальности
import uuid
unique_name = f"{uuid.uuid4().hex}_{safe}.jpg"
6. Ключевые моменты
get_valid_filenameзащищает файловую систему от опасных имен всего одним строчкой кода.- Используйте его каждый раз, когда преобразуете ввод пользователя или произвольную строку в имя файла.
- Код аккуратный, кроссплатформенный и безопасный.
Совет: Если вы хотите оставить пробелы или сохранить юникод, вы можете объединить его с
slugifyили создать пользовательский хелпер, но в большинстве случаевget_valid_filename— лучший вариант.
Комментариев нет.