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が最適です。
コメントはありません。