本文へスキップ
BecomeCoder

Djangoコース · 第4章 フォームと入力 · レッスン17

Djangoフォーム ― forms.Form とバリデーション

ブラウザで完結

導入

request.POST.get(...) を1つずつ検査するのは大変で、ミスも起きます。Django のフォームクラスを使うと、項目の定義と検証をまとめて宣言でき、正しい値だけを安全に取り出せます。

説明

forms.Form継承し、フィールドを宣言します。データを渡して is_valid() を呼ぶと検証が走り、通れば cleaned_data に「型変換済み・検証済み」の値が入ります。

import django
from django.conf import settings
if not settings.configured:
    settings.configure(DEBUG=True, SECRET_KEY="dev", INSTALLED_APPS=[])
    django.setup()

from django import forms

class ContactForm(forms.Form):
    name = forms.CharField(max_length=10)               # 必須・10文字まで
    age = forms.IntegerField(min_value=0, max_value=150) # 整数・範囲チェック
    email = forms.EmailField()                          # メール形式チェック

# ① 正しい入力
f = ContactForm(data={"name": "Aki", "age": "20", "email": "aki@example.com"})
print("正しい?", f.is_valid())
print("cleaned:", f.cleaned_data)   # age は文字列 "20" → 整数 20 に変換される

# ② 誤った入力
bad = ContactForm(data={"name": "", "age": "999", "email": "not-an-email"})
print("正しい?", bad.is_valid())
print("errors:", dict(bad.errors))  # 項目ごとのエラー文
  • フィールドの種類(CharField / IntegerField / EmailField …)が、そのまま検証ルールになります。
  • is_valid()True のときだけ cleaned_data を使います。age文字列で来ても整数に変換されている点に注目(型の面倒も見てくれる)。
  • False のときは form.errors に「どの項目がなぜダメか」が入ります。これをそのまま画面に出せば、親切なエラー表示になります。

ビューでの定番の形はこうです。

def contact(request):
    if request.method == "POST":
        form = ContactForm(request.POST)
        if form.is_valid():
            # form.cleaned_data を使って保存など
            return redirect("/thanks/")
    else:
        form = ContactForm()          # 空のフォーム
    return render(request, "contact.html", {"form": form})

やってみよう

ContactForm(data={...}) の値を変えて is_valid()errors の変化を見ましょう。age"abc" を入れると「整数を入力してください」、email を変な形式にすると「有効なメールアドレスを」というエラーが出ます。

演習

ContactForm に、必須の文字列フィールド messageforms.CharField)を追加してください。そのうえで message を空にした baderrorsmessage が含まれることを確認します。

ヒント1を見る

クラス内に message = forms.CharField() を追加します。

ヒント2を見る

baddata から message を外す(または "" にする)と、dict(bad.errors)message が現れます。

実際に動かしてみよう

本文のサンプルや演習のコードは、コードブロック右上の「コピー」ボタンでコピーして、下のエディタに貼り付ければそのまま実行できます。

Python — ライブラリ付きで実行(Pyodide)

numpy / pandas / matplotlib が使える本物のPython(Pyodide)を読み込みます。初回のみ読み込みに少し時間がかかります(以降はブラウザにキャッシュされます)。
スクロールして表示された時点でも自動で読み込まれます。