3秒でわかる
入力された値が決めた条件を満たすか確かめる処理。壊れたデータを保存する前にはじき、どこが誤りなのかを利用者へ返すための門番です。
もう少し詳しく
どういうものか
バリデーションは、受け取った値が期待する形式や範囲に収まっているかを確かめ、外れていれば処理を止めて理由を返す仕組みです。必須かどうか、文字数、型、値の範囲、既存データとの重複といった観点で検査します。検査に通った値だけを、そのあとの計算や保存へ渡します。
なぜ必要か
一度おかしなデータが保存されると、影響はそこで終わりません。空文字の日付が入った行は集計のたびに例外を出し、修正には過去データの洗い直しが必要になります。入り口で止めるほうが圧倒的に安く済みます。また、フォームの入力ミスを具体的な文言で返せると、利用者が自力で直せます。
具体例
def validate_signup(form):
errors = {}
email = form.get("email", "").strip()
if not email:
errors["email"] = "メールアドレスを入力してください"
elif "@" not in email:
errors["email"] = "メールアドレスの形式が正しくありません"
age = form.get("age")
if age is <a href="/glossary/none" class="text-primary font-medium underline underline-offset-2 hover:text-primary-dark">None</a> or not str(age).isdigit():
errors["age"] = "年齢は数字で入力してください"
elif not (0 <= int(age) <= 120):
errors["age"] = "年齢の範囲が不正です"
return errors # 空の辞書なら合格複数のエラーをまとめて返す形にすると、利用者が1項目ずつ送信し直す手間を避けられます。
つまずきやすいところ
最大の落とし穴は、フロントエンドの検査だけで安心してしまうことです。ブラウザの検査は入力体験を良くするためのもので、リクエストは開発者ツールやcurlから直接送れます。サーバー側で同じ検査を必ずもう一度行います。もうひとつは、電話番号やメールアドレスを厳しすぎる正規表現で弾いてしまう例です。実在する形式まで拒否すると、利用者は登録を諦めます。
似た用語との違い
| 語 | 何をするか |
|---|---|
| バリデーション | 値が条件を満たすか検査して可否を返す |
| サニタイズ | 危険な文字を除去したり無害化したりする |
| エスケープ | 出力先の文法に合わせて特殊文字を変換する |
覚え方
検査は「入り口で1回」ではなく「境界を越えるたび」に行います。画面からサーバーへ、サーバーからDBへ、外部APIから自分のシステムへ、それぞれが境界です。信用できるのは自分が検査した値だけと考えると、どこに書くべきか迷わなくなります。