Djnagoの入力フォームにバリデーション(validation)機能を実装したのでその方法を解説します。
今回はURLのバリデーションを作成します。
実装例
・まず次のような画面を作ります。
・URLが未入力の場合に送信ボタンを押すと次のように表示されます。
・URLが正しく入力されていない時に送信ボタンが押された場合は「URLを正しく入力してください」と表示します。
・入力が正しい時に送信ボタンが押された場合は、実行結果欄に入力フォームで記述した内容を表示します。
バリデーションとは
バリデーションとは、記述・入力されたデータが、あらかじめ規定された条件などに適合しているかどうかを検証・確認することです。
要するにWebページなどでEメールアドレスを入れる欄に、関係ない文字列を入れると怒られるあれです。
編集するファイル
バリデーションを実装するには以下の4つのファイルを編集します。
- forms.py
- urls.py
- views.py
- formを表示するhtmlファイル
ソースコードと解説
forms.py
まず、forms.pyで入力フォーム部分の作成を行います。
今回は、URLとテキストを入力するフォームを定義します。
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の部分で設定を行っています。
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 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/」、キーワードに「ほげほげ」と入力し、送信ボタンを押しています。