簡易書籍登録アプリケーションの説明(バリデーション版)

8.3 簡易書籍登録アプリケーションの説明(バリデーション版)

7章で作成したアプリケーションをもとに、Formクラスを利用したバリデーション処理が実際どのような流れで動作しているのかを説明していきます。

8.3.1 formBookクラス(Formのサブクラス)

まず初めに、FormのサブクラスformBookクラスから確認していきましょう。

■ソースコード
【ファイル名:forms.py】

まずFormは該当のプロジェクトのディレクトリ(bmsdjango)直下にある「forms.py」内に定義します。
Formとして3~12行目でformBookクラスを定義しており、Formは「django.db.forms.Form」のサブクラスであるため、3行目で「class formBook(forms.Form)」と記載されています。

    class formBook(forms.Form):
	

また6~13行目で宣言されている変数は、各フィールドのデータ型、フィールド名、文字数などを決定するためのものです。

    #isbn
    isbn = forms.CharField(label='ISBN',min_length=4,max_length=10)

    #タイトル
    title = forms.CharField(label='TITLE' ,error_messages={'required':"Titleを入力ください"})

    #価格
    price = forms.IntegerField(label='価格')
	

具体的には、isbnやtitleのように文字列を格納する場合には、forms.CharFielsメソッドの戻り値を変数に代入します。

引数labelには画面に表示させるフィールド名、min_lengthには文字数の下限、max_lengthには文字数の上限を設定できます。
また引数requiredによって必須項目かどうかを指定することができます。
「required=True」と指定すると必須項目になり、「required=False」と指定すると必須項目でなくなりますが、デフォルト(未指定)で必須項目になりますので、今回のように指定しなくても必須項目として機能します。

    #タイトル
    title = forms.CharField(label='TITLE' ,error_messages={'required':"Titleを入力ください"})
	

引数error_messagesは、エラーが発生した場合に表示されるメッセージを設定できます。エラーが発生した場合、バリデーションの種類によってデフォルトでエラーメッセージが設定されています。
こちらの引数ではキー値にバリデーションを指定することで、エラーメッセージの内容を上書きすることができます。
今回のケースではrequiredのエラーが発生した際に、「Titleを入力ください」と表示させるよう上書きします。

8.3.2 View(views.py)

続いて今回のViewに該当するinsert関数において、Formを介してバリデーション処理をどのように行っているのかを確認していきましょう。

■ソースコード
【ファイル名:bmsdjango/views.py】

まず22行目ではFormのサブクラスであるformBookクラスのインスタンスを作成しています。
23行目ではエラー内容を格納するための変数error、24行目ではPOST送信の有無を判定するための変数postCheckを宣言しています。

    form = formBook()
    error = ""
    postCheck = False
	

これらの変数はinsert.htmlを表示させるか、一覧画面へ遷移させるかを判定する際に使用します。

■POST送信があった場合の処理

26~39行目ではPOST送信があった場合の処理が実行されます。
POST送信があった場合の処理を確認すると、まず27行目で変数postCheckにPost送信が行われたことを示すためにTrueを代入します。

    if (request.method == 'POST'):
        postCheck = True
        form = formBook(request.POST)
	

続いて変数formには送信データ(request.POST)を引数にformBookクラスのインスタンスを代入します。
Formは入力フォームの作成からバリデーションエラーの確認を行うことができるクラスです。

送信データを引数に加えることで、送信データが含む入力フォームの生成や、送信データからバリデーションの判定を行うことができます。

◆バリデーションエラーの判定

30行目の「is_valid()メソッド」はバリデーションエラーがなければTrue、エラーがあればFalseが戻り値に返すメソッドですので、30~37行目ではバリデーションエラーがなかった場合の処理になります。
処理の内容を確認すると、31~34行目では送信データを各変数に格納しています。

    if (form.is_valid()):
        isbn = request.POST["isbn"]
        title = request.POST["title"]
        price = request.POST["price"]
	

またisbnは一意的な値であるため、35行目ではisbnが既存のデータに重複しているかの判定を行っています。重複があった場合、変数errorに「’ISBNの内容に誤りがあります’」が格納されます。

    if Book.objects.filter(isbn=isbn).exists():
        error = 'ISBNの内容に誤りがあります'
	

以上、バリデーションエラーがなかった場合の処理ですが、反対にバリデーションエラーがあった場合、38、39行目の処理が実行されます。

    else:
        error = '入力内容に誤りがあります。'
	

バリデーションエラーがあった場合、変数errorに「’入力内容に誤りがあります。’」が格納されます。

以上、POST送信が行われた場合の処理です。

■データベースへの登録処理

続いて41~45行目の処理の説明をします。41行目からpostCheckの値がTrue、errorの値が「’’」だった場合に実行される処理です。
つまりはPOST送信が行われ、かつerrorがなかった場合に41~45行目が実行されます。

    if postCheck and (error == ""):
        book = Book(isbn=isbn,title=title,price=price)
        book.save()

        return redirect(to='./list')
	

42、43行目は前章までで解説した通り、送信データをデータベースに登録するための処理であり、45行目は一覧画面へリダイレクトさせるための処理です。
POST送信が無事、行われた場合だけデータベースへの登録を行うために、該当のif文のブロック内にこれらの処理が記載されています。

■登録画面の表示

一方、何かしらのエラーがあった場合、POST送信が行われていない場合は、登録画面(insert.html)を表示させます。
登録画面(Template)には入力フォームを表示させるためのform(formBookクラスのインスタンス)、エラーがある場合にはエラー内容を表示させるための変数errorを引き渡す必要があります。
そのため47~50行目ではTemplateに引き渡す辞書型変数paramsを宣言しており、キー値「’form’」には変数form、「’message’」には変数errorを設定しています。

    params = {
    'form':form,
    'message':error
    }
	

最後、52行目では先ほどの変数paramsを引き渡す形でTemplateとして「insert.html」を表示されせます。

    return render(request, 'insert.html',params)
	

8.3.3 insert.html(テンプレートファイル)

最後に、画面にデータを表示するテンプレートを見ていきましょう。

■ソースコード
【ファイル名:insert.html】

■エラーメッセージを出力する

前章までの変更点の一つはエラーメッセージの出力です。41行目で変数messageの値を出力しています。
変数messageは、View(insert関数)から渡されたものです。具体的なエラーがあった場合、エラー内容が格納されますので、エラー内容が表示されます。

	<p>{{message}}</p>
	

■入力フォームを表示させる

また入力フォームにおける記載方法も前章からの変更点です。表示内容は変わっていませんが、ISBN、TITLE、価格の項目をForm(変数form)で表示させています。

	{{form.as_table}}
	

具体的には46行目で「as_tableメソッド」を使って表示させています。通常の記載方式と比べて、簡潔に表示させることができます。


NEXT>> 8.4 バリデーションの一覧