2021.06.19  

【Django】入力Formに検証機能を実装する。(バリデーション- validation)

Djnagoの入力フォームにバリデーション(validation)機能を実装したのでその方法を解説します。

今回はURLのバリデーションを作成します。

実装例

・まず次のような画面を作ります。




・URLが未入力の場合に送信ボタンを押すと次のように表示されます。


・URLが正しく入力されていない時に送信ボタンが押された場合は「URLを正しく入力してください」と表示します。


・入力が正しい時に送信ボタンが押された場合は、実行結果欄に入力フォームで記述した内容を表示します。


バリデーションとは

バリデーションとは、記述・入力されたデータが、あらかじめ規定された条件などに適合しているかどうかを検証・確認することです。

要するにWebページなどでEメールアドレスを入れる欄に、関係ない文字列を入れると怒られるあれです。

編集するファイル

バリデーションを実装するには以下の4つのファイルを編集します。

  1. forms.py
  2. urls.py
  3. views.py
  4. formを表示するhtmlファイル

ソースコードと解説

forms.py

まず、forms.pyで入力フォーム部分の作成を行います。
今回は、URLとテキストを入力するフォームを定義します。

forms.py
from django import forms

class TestForm(forms.Form):
    url_data = forms.URLField(max_length=100, required=True,
                              widget=forms.TextInput(
                                   attrs={'placeholder': 'https://rurukblog.com/'}))
    key_word = forms.CharField(max_length=100, required=False,
                               widget=forms.TextInput(
                                     attrs={'placeholder': 'キーワード'}))


Field

上記コードのURLFieldでURLのフォームを、CharFieldでテキストのフォームを作成できます。


max_length

引数にmax_lengthを指定すると、フォームに入力する最大文字数を設定できます。


equired

required=Trueと設定するとそのフォームへの入力を必須にします。

requiredは設定しなくてもデフォルトでTrueとなります。

逆に入力を任意にしたい場合はrequiredをFalseに設定します。

required=Trueはテンプレート(html)で <input type="submit"> を使用して送信ボタンを作成した場合は、フォームが未入力状態で送信ボタンを押すとDjangoの機能で警告を行ってくれます。

しかし、それ以外の手段(aタグやdivタグなど)でボタンを作成した場合は機能しません。

inputタグ以外でボタンを作成した場合は、views.pyのform.is_valid()で判定を行うようにします。

form.is_valid()は、テンプレートで入力された情報がforms.pyで設定した条件通りである場合はTrueを、条件に違反する場合はFalse返すメソッドです。

max_lengthに設定した条件も、form.is_valid()で判定されます。



<input> で作成した送信ボタンをフォーム未入力で押下した場合の動き

※ equired=Trueを設定した入力フォームを空の状態で、<input type="submit">で作ったボタンを押すと、上記のようにDjangoの機能で警告文を表示してくれる。


widget=forms.TextInput(attrs={'placeholder': '任意の文字列'}

プレースホルダーです。
'placeholder': の右側に文字列を設定すると、入力フォームの背景にその文字列が表示されます。


urls.py

URLとviews.pyを紐づけます。(先ほどフォームで設定したURLとは別もので、Djangoでページ遷移を行うためのURLです)

今回はブラウザでURLにhttp://127.0.0.1:8000/form-testと指定すると、views.pyのFormTestViewが実行されるように設定します。(8000部分はWebサーバーのPort番号。実行環境により異なる)

下記コードではurlpatternsの部分で設定を行っています。

urls.py
from django.urls import path
from . import views

app_name = 'app'

urlpatterns = [
    path('form-test', views.FormTestView, name='form-test'),
]


views.py

先ほどurls.pyで設定したURLにアクセスすると FormTestView(request)が実行される。

from django.shortcuts import get_object_or_404, redirect, render
from .forms import TestForm

def FormTestView(request):

    # GETメソッドでページを開くときはformの情報だけ送る。
    params = {'url_data': '', 'key_word': ''}
    params['form'] = TestForm

    # テンプレートで送信ボタンが押された場合こちらを実行
    if request.method == 'POST':
        form = TestForm(request.POST)

        # バリデーション(formの入力パターンチェック)
    # テンプレートで受け取ったデータに問題がなければこの処理を実行
        if form.is_valid():
            params['error_message'] = None
            params['post_url_data'] = request.POST['url_data']
            params['post_key_word'] = request.POST['key_word']
        # テンプレートで受け取ったデータがformの条件と違う場合はこの処理を実行
        else:
            params['error_message'] = 'URLを正しく入力してください'
            params['form'] = form

     # views.pyで処理したデータをテンプレートに返す
    return render(request, 'app/form_test.html', params)

URL経由でアクセスするとまず、以下の処理が実行される。

    # GETメソッドでページを開くときはformの情報だけ送る。
    params = {'url_data': '', 'key_word': ''}
    params['form'] = TestForm
    # -- 省略 --
    return render(request, 'app/form_test.html', params)

この処理はforms.pyで作成したTestFormメソッドをテンプレートに返しているだけです。

テンプレートでデータを入力し、送信ボタンを押した場合は以下の処理がTrueとなり、次の処理が実行されます。

    # テンプレートで送信ボタンが押された場合こちらを実行
    if request.method == 'POST':
        form = TestForm(request.POST)

以下コードはテンプレートの入力フォームに記述された内容をforms.pyで設定した条件に合致しているかを判定している部分です。

その判定は form.is_valid() メソッドが行っています。

forms.pyに設定した通りならTrue、そうでないならFalseを返します。

# バリデーション(formの入力パターンチェック)
# テンプレートで受け取ったデータに問題がなければこの処理を実行
    if form.is_valid():
        params['error_message'] = None
        params['post_url_data'] = request.POST['url_data']
        params['post_key_word'] = request.POST['key_word']
    # テンプレートで受け取ったデータがformの条件と違う場合はこの処理を実行
    else:
        params['error_message'] = 'URLを正しく入力してください'
        params['form'] = form

 # views.pyで処理したデータをテンプレートに返す
return render(request, 'app/form_test.html', params)

ここではTrueの場合、入力フォームで記述した内容をそのままテンプレートに送信しています。

Falseの場合は、'error_message'にURLを正しく入力してくださいを設定しています。

この'error_message'をテンプレートに記述すると、Forms.pyの条件通りでなかった場合にこのメッセージを画面に表示できます。


form_test.html

最後にテンプレート部分の紹介です。

form_test.html
  <form method="POST" name="form">
    {% csrf_token %}
    <b>ULR</b>
    {{ form.url_data}}<br><br>
    {% if error_message is not None %}
      <b class="input_form_error">{{ error_message }}</b><br><br>
    {% endif %}
    <b>キーワード</b>
    {{ form.key_word }}<br><br>
    <input type="submit">
  </form>
<b>実行結果</b>
<p>{{ post_url_data }}</p>
<p>{{ post_key_word }}</p>

{{ form.url_data}}、{{ form.key_word }}を記述すると、forms.pyで設定した入力フォームが表示されます。

   {% if error_message is not None %}
      <b class="input_form_error">{{ error_message }}</b><br><br>
    {% endif %}

この部分は、バリデーションの判定でFalseになった時にviews.pyで設定したメッセージが表示されます。

Trueであれば何も表示されません。

<b>実行結果</b>
<p>{{ post_url_data }}</p>
<p>{{ post_key_word }}</p>

バリデーション判定がTrueだった場合はこの部分が出力されます。

views.pyで設定したように、入力フォームで記述した内容がここに出力されます。

結果

このようにコードを作成すると冒頭で紹介したような処理を実現できます。

・「http://127.0.0.1:8000/form-test」にアクセスする


・入力フォームのURLが未入力の場合に送信ボタンを押すと、次のような表示がでる。


・入力フォームのURLが正しく入力されていない場合は、「URLを正しく入力してください」と表示されます。


・入力フォームのURLが正しく入力されている場合は、実行結果欄の下にフォームで記述した内容がそのまま表示されます。




ここではURL部分に「https://rurukblog.com/」、キーワードに「ほげほげ」と入力し、送信ボタンを押しています。


Djangoの参考書

コメント
現在コメントはありません。
コメントする
コメント入力

名前 (※ 必須)

メールアドレス (※ 必須 画面には表示されません)

送信