Python | Django | フォームにおけるフィールドの使い方

2021年7月7日

公開日:2021/7/7

Pythonには,DjangoというWebアプリケーションフレームワークがある.フレームワークのため,Djangoを利用するとWebアプリを通常よりも短時間で開発することが可能になる.

前記事にて,「フォームの使い方」を記した.前記事での設定をそのまま引き継いだ上で,本記事では,「フォームにおけるフィールドの使い方」を以下4つの構成にて記す.

  1. フォームにおけるフィールドの基本的な利用
  2. フィールドの引数によるカスタマイズ
  3. クラス追加によるレイアウト変更
  4. コンストラクタ上書きによるレイアウト変更

◆実施環境

Python 3.8.8
Django 3.2.3

■フォームにおけるフィールドの使い方

  1. フォームにおけるフィールドの基本的な利用

利用できる主なフィールドの一覧は以下になる.

(a)BooleanField: チェックボックス入力となる.

(b) CharField: テキスト入力となる.最大長さ(max_length)や最小長さ(min_length)を設定することができる.

(c) ChoiceField: 選択となる.

(d) DateField: 日付入力となる.

(e) DateTimeField: 日付と時間入力となる.

(f) DecimalField: 数字入力となる.最大値(max_value)や最小値(min_value)を設定することができる.

(g) EmailField: Email入力となる.

(h) MultipleChoiceField: 複数選択となる.

(i) URLField: URL入力となる.

”form_app/forms.py”に追記し,以下のように編集する.

from django import forms

class ChocolateInfo(forms.Form):
  Chocolate_name = forms.CharField(max_length=50)
  Chocolate_maker = forms.CharField(max_length=50)
  mail = forms.EmailField()
  is_available_for_sale = forms.BooleanField()
  birthday = forms.DateField() 
  price = forms.DecimalField()
  flavor = forms.ChoiceField(choices=( 
    (1, 'Original Chocolat'), 
    (2, 'Double Chocolat'), 
    (3, 'Original White'), 
    (4, 'Rich Matcha'), )
    ) 
  maker_factory = forms.MultipleChoiceField(choices=( 
    (1, 'Ibaraki Moriya-city'), 
    (2, 'Saitama Sakado-city'), 
    (3, 'Aichi Inazawa-city'), 
    (4, 'Osaka Takatsuki-city'), )
    ) 
  homepage = forms.URLField()

“form_app/views.py"を以下のように編集する.

from django.shortcuts import render

from . import forms

def index(request):
  return render(request, 'form_temp/index.html')

def form_page(request):
  form = forms.ChocolateInfo()
  
  if request.method == 'POST':
    form = forms.ChocolateInfo(request.POST)
    if form.is_valid():
      print('submission is successful')
      print(form.cleaned_data) # 変更箇所
    else:
      print('submission is failed')

  return render(
    request,'form_temp/form_page.html', context={
      'form':form
    }
  )

ターミナルを開き,”conda activate 仮想環境名”を実行し,仮想環境に移行する(移行方法の詳細はこちら).”form_project”のディレクトリで”python manage.py runserver”を実行する.私の場合,以下のように実行する.

(djangoenv) C:\Users\shiro\Desktop\210517_python development\myformtest\form_project
>python manage.py runserver

実行すると,ターミナルに以下が出力される.

System check identified no issues (0 silenced).
July 07, 2021 - 03:18:57
Django version 3.2.3, using settings 'form_project.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.

“http://127.0.0.1:8000/”をクリックし,ブラウザを開くと以下のように表示される.

“http://127.0.0.1:8000/form_application/"をクリックすると以下ページに遷移する.

上記の"Go to Form"をクリックすると以下ページに遷移する.

以下のように記述し,"submit"をクリックする.

ターミナルには以下が出力される.

submission is successful

{'chocolate_name': 'Fran1', 'chocolate_maker': 'Meiji', 
'mail': 'Fran1@gmail.com', 'is_available_for_sale': True, 
'birthday': datetime.date(1999, 1, 1), 'price': Decimal('200'), 
'flavor': '2', 'maker_factory': ['2', '4'], 
'homepage': 'https://www.shelokuma.com'} 

[07/Jul/2021 03:30:18] "POST 
/form_application/form_page/ HTTP/1.1" 200 2156
  1. フィールドの引数によるカスタマイズ

フィールドの引数には以下種類がある.

(a) label: フィールドに対するラベルを付ける

(b) initial: フォームで表示される際の初期値を指定する.

(c) widget: HTMLで入力する外観を変える.
— RadioSelect: 単数選択
— CheckboxSelectMultiple: 複数選択

(d) required: Falseで任意とする

(e) max_length: 文字列の最長

(f) min_length: 文字列の最短

(g) max_value: 最大値

(h) min_value: 最小値

上記の引数を利用して,”form_app/forms.py”を以下のように編集する.

from django import forms

class ChocolateInfo(forms.Form):
  chocolate_name = forms.CharField(label='チョコレート名', max_length=50)
  chocolate_maker = forms.CharField(label='チョコレートメーカー', max_length=50)
  mail = forms.EmailField(label='メールアドレス')
  is_available_for_sale = forms.BooleanField(label='販売中')
  birthday = forms.DateField(required=False, label='開発日')
  price = forms.DecimalField(initial=300, max_value=1000, label='価格')
  flavor = forms.ChoiceField(choices=(
    (1, 'Original Chocolat'),
    (2, 'Double Chocolat'),
    (3, 'Original White'),
    (4, 'Rich Matcha'),
  ), widget=forms.RadioSelect, label='味')
  maker_factory = forms.MultipleChoiceField(choices=(
    (1, 'Ibaraki Moriya-city'),
    (2, 'Saitama Sakado-city'),
    (3, 'Aichi Inazawa-city'),
    (4, 'Osaka Takatsuki-city'),
  ), widget=forms.CheckboxSelectMultiple, label='メーカー工場')
  homepage = forms.URLField(
    label='ホームページ',
    widget=forms.TextInput(attrs={'placeholder':'https://www.shelokuma.com'})
  )

ターミナルから仮想環境に移行し,”form_project”のディレクトリで”python manage.py runserver”を実行する.その後,"http://127.0.0.1:8000/form_application/"をクリックすると以下ページに遷移する.

上記の"Go to Form"をクリックすると,以下ページ"http://127.0.0.1:8000/form_application/form_page"に遷移する."label"引数の利用により各項目は変わり,"味"や"メーカー工場"の項目は,チェックボックスに変わった."initial"引数により,"価格"の項目には初期値が含まれている.また,"ホームページ"の項目には,薄い文字でURLの書き方が含まれている.

  1. クラス追加によるレイアウト変更

“http://127.0.0.1:8000/form_application/form_page"に遷移し,右クリックをし,"検証"を選択する.(ブラウザはChrome, バージョン: 91.0.4472.124)

以下のように,ホームページのタイトルは,青文字が関連し,ホームページの入力部は,赤文字が関連している.

ホームページの入力部とタイトルを変更するため,以下(i)と(ii)を実施していく.

(i) ホームページの入力部:classがないので追記する
(ii) ホームページのタイトル:"id_homepage"を利用

”form_app/forms.py”にコード「’class’:’url_class’,」を追記し,以下のように編集する.

from django import forms

class ChocolateInfo(forms.Form):
  chocolate_name = forms.CharField(label='チョコレート名', max_length=50)
  chocolate_maker = forms.CharField(label='チョコレートメーカー', max_length=50)
  mail = forms.EmailField(label='メールアドレス')
  is_available_for_sale = forms.BooleanField(label='販売中')
  birthday = forms.DateField(required=False, label='開発日')
  price = forms.DecimalField(initial=300, max_value=1000, label='価格')
  flavor = forms.ChoiceField(choices=(
    (1, 'Original Chocolat'),
    (2, 'Double Chocolat'),
    (3, 'Original White'),
    (4, 'Rich Matcha'),
  ), widget=forms.RadioSelect, label='味')
  maker_factory = forms.MultipleChoiceField(choices=(
    (1, 'Ibaraki Moriya-city'),
    (2, 'Saitama Sakado-city'),
    (3, 'Aichi Inazawa-city'),
    (4, 'Osaka Takatsuki-city'),
  ), widget=forms.CheckboxSelectMultiple, label='メーカー工場')
  homepage = forms.URLField(
    label='ホームページ',
    widget=forms.TextInput(attrs={'class':'url_class','placeholder':'https://www.shelokuma.com'}) # 追記箇所
  )

“form_project/settings.py"に追記する.以下は"settings.py"の一部になる.

from pathlib import Path
import os

BASE_DIR = Path(__file__).resolve().parent.parent
TMP_DIR = os.path.join(BASE_DIR, 'templates')
STATIC_DIR = os.path.join(BASE_DIR, 'static') # 追記箇所

また,"form_project/settings.py"に追記する.以下は"settings.py"の一部になる.

STATIC_URL = '/static/'
STATICFILES_DIRS = [ # 追記箇所
  STATIC_DIR
]

“form_project"に"static"フォルダを作成し,その中に"css"フォルダを作成する."css"フォルダの中に"style.css"を作成する.フォルダ構成は以下になる.

上記(i)向け,および,”form_app/forms.py”に追記したコードが「’class’:’url_class’,」ため,以下"form_project/static/css/style.css"に(A)を記述する.また,上記(ii)向けのため,(B)を記述する.

.url_class{ # 以下追記箇所(A)
  width: 150%;
  font-size: 30px;
  color: green;
}

label[for="id_homepage"]{ # 以下追記箇所(B)
  color: red;
  font-size: 20px;
}

“form_project/templates/form_temp/form_page.html"に以下を追記し,編集する.

<!DOCTYPE html>
<html> 
<head> 
<meta charset="utf-8">
<title>Form</title> 
{% load static %} # 追記箇所
<link rel="stylesheet" href="{% static 'css/style.css' %}"> # 追記箇所
</head>
<body> 
<form method="POST">
{% csrf_token %}
<table>
{{form.as_table}}
</table>
<input type="submit" value="submit">
</form>
</body> 
</html>

“http://127.0.0.1:8000/form_application/form_page"を更新すると,上記(i)と(ii)は以下のように反映された.

(i) ホームページの入力部:入力部は赤枠のように変更(幅:150%, フォントサイズ:30px, 文字色:緑)となった.
(ii) ホームページのタイトル:タイトルは青枠のように変更(フォントサイズ:20px, 文字色:赤)となった.

  1. コンストラクタ上書きによるレイアウト変更

“http://127.0.0.1:8000/form_application/form_page"を開くと以下画面に遷移する.以下のように,"味"と"メーカー工場"のタイトルのチェックボックスの前に黒丸が入っている.本項では,コンストラクトの上書きにより,当該黒丸を削除する作業を記す.

”form_app/forms.py”に追記し,以下のように編集する.

from django import forms

class ChocolateInfo(forms.Form):
  chocolate_name = forms.CharField(label='チョコレート名', max_length=50)
  chocolate_maker = forms.CharField(label='チョコレートメーカー', max_length=50)
  mail = forms.EmailField(label='メールアドレス')
  is_available_for_sale = forms.BooleanField(label='販売中')
  birthday = forms.DateField(required=False, label='開発日')
  price = forms.DecimalField(initial=300, max_value=1000, label='価格')
  flavor = forms.ChoiceField(choices=(
    (1, 'Original Chocolat'),
    (2, 'Double Chocolat'),
    (3, 'Original White'),
    (4, 'Rich Matcha'),
  ), widget=forms.RadioSelect, label='味')
  maker_factory = forms.MultipleChoiceField(choices=(
    (1, 'Ibaraki Moriya-city'),
    (2, 'Saitama Sakado-city'),
    (3, 'Aichi Inazawa-city'),
    (4, 'Osaka Takatsuki-city'),
  ), widget=forms.CheckboxSelectMultiple, label='メーカー工場')
  homepage = forms.URLField(
    label='ホームページ',
    widget=forms.TextInput(attrs={'class':'url_class','placeholder':'https://www.shelokuma.com'}))

    def __init__(self,*args,**kwargs): # 以下追記箇所
      super(ChocolateInfo, self).__init__(*args, **kwargs)
      self.fields['flavor'].widget.attrs['id'] = 'id_flavor'
      self.fields['maker_factory'].widget.attrs['class'] = 'maker_factory_class'

“form_project/static/css/style.css"に追記し,以下のように編集する.

.url_class{
  width: 150%;
  font-size: 30px;
  color: green;
}

label[for="id_homepage"]{
  color: red;
  font-size: 20px;
}

#id_flavor{ # 以下追記箇所
list-style: none;
}
.maker_factory_class{
list-style: none;
}

“http://127.0.0.1:8000/form_application/form_page"を更新すると,赤枠から黒丸が削除された.

■参照

https://docs.djangoproject.com/ja/3.1/ref/forms/fields/

以上