DjangoのChoiceFieldのわかりやすい使い方・書き方
- 作成日: 2021-08-18
- 更新日: 2023-12-26
- カテゴリ: Django
DjangoのChoiceFieldのわかりやすい使い方
Djangoではフォームを使うことが出来ますが、フォームのフィールドにはChoiceFieldというフィールドを指定することが出来ます。
ChoiceField
は画面上ではプルダウンメニューで表示されるフィールドです。
複数の選択肢を定義したフィールドを使いたい場合にぴったりなフィールドと言えます。
結論から言うとChoiceField
を使ったDjangoのフォームは↓のように書きます。
from django import forms
from django.db import models
class FoodChoices(models.TextChoices):
BREAD = 'bread', 'パン'
RICE = 'rice', 'ご飯'
FISH = 'fish', '魚'
MEAT = 'meat', '肉'
class FoodForm(forms.Form):
food = forms.fields.ChoiceField(
choices=FoodChoices.choices,
required=True,
label='食べ物',
# widget=forms.widgets.Select,
)
この記事ではDjangoのChoiceField
について詳細に見ていきます。
具体的には↓になります。
- ChoiceFieldの定義方法
- 実際にChoiceFieldを使ってみる
- ChoiceFieldの構造
関連記事
DjangoのBooleanFieldの使い方: 真偽値, True, False
DjangoのDateTimeFieldの詳しい使い方: 日付と時刻を扱うフィールド
ChoiceFieldの定義方法
ChoiceField
はdjango.forms.fields
に保存されています。
ChoiceField
を使ったフォームを定義するには↓のようにします。
from django import forms
from django.db import models
class FoodChoices(models.TextChoices):
BREAD = 'bread', 'パン'
RICE = 'rice', 'ご飯'
FISH = 'fish', '魚'
MEAT = 'meat', '肉'
class FoodForm(forms.Form):
food = forms.fields.ChoiceField(
choices=FoodChoices.choices,
required=True,
label='食べ物',
# widget=forms.widgets.Select,
)
↑の場合、FoodForm
というのがChoiceField
を使っているフォームです。
このフォームの属性food
はChoiceField
です。
ChoiceField
の引数にはchoices
, required
, label
などを指定します。
ChoiceField
はデフォルトではforms.widgets.Select
をウィジェットとして使います。
引数choices
に選択肢の定義を渡します。
選択肢の定義はFoodChoices
というクラスで行っています。
FoodChoices
はdjango.db.models.TextChoices
を継承したクラスです。
TextChoices
は↑のように定数名(BREAD
やRICE
など)に対して「値, 表示ラベル」というふうにタプルで定義します。
この表示ラベルがフォームのプルダウンで表示されて、値が実際に選択された場合の値になります。
選択肢の定数の参照方法
選択肢(FoodChoices
)の定数は参照することが可能です。
具体的には↓になります。
- 「定数.name」で定数の名前を参照
- 「定数.value」で定数の値を参照
- 「定数.label」で定数のラベルを参照
たとえば↓のようなビューを定義します。
from myapp.forms import FoodChoices
from django.http import HttpResponse
def enum_view(request):
html = f'{FoodChoices.BREAD.name}: {FoodChoices.BREAD.value}, {FoodChoices.BREAD.label}<br />'
html += f'{FoodChoices.RICE.name}: {FoodChoices.RICE.value}, {FoodChoices.RICE.label}<br />'
return HttpResponse(html)
↑の場合、FoodChoices
をforms.py
からインポートしています。
そしてFoodChoices.BREAD
とやってパンの定数を参照しています。
FoodChoices.BREAD.name
で定数の名前、そしてFoodChoices.BREAD.value
で定数の値を参照します。さらにFoodChoices.BREAD.label
でラベルを参照します。
↑のビューを実行すると↓のような出力になります。
BREAD: bread, パン
RICE: rice, ご飯
旧来の定義方法
さきほどのTextChoices
を使った定義方法は比較的に新しい定義方法になります。
旧来の方法は↓のようになります。
class OldFoodForm(forms.Form):
FOOD_CHOICES = (
('bread', 'パン'),
('rice', 'ご飯'),
('fish', '魚'),
('meat', '肉'),
)
food = forms.fields.ChoiceField(
choices=FOOD_CHOICES,
required=True,
label='古い食べ物',
)
↑のように選択肢を定義したFOOD_CHOICES
というタプルを定義します。
タプルの中にタプルで「値, 表示テキスト」という順番に書きます。
こうすることで選択肢が機能します。
新しい方法と比べると、旧来の方法は定数を参照したい場合にタプルのインデックスで指定しなければいけません。
新しい方では定数名で参照できるので、利便性では新しい方法のほうが高いと言えそうです。
実際にChoiceFieldを使ってみる
実際にChoiceField
を定義したフォームを使ってみます。
まずurls.py
を定義します。
from django.contrib import admin
from django.urls import path
from myapp.views import home_view
urlpatterns = [
path('admin/', admin.site.urls),
path('', home_view),
]
そしてビューを定義します。
from django.shortcuts import render
from django.http import HttpResponse
from myapp.forms import FoodForm
def home_view(request):
if request.method == 'GET':
return render(request, 'myapp/home.html', {
'form': FoodForm(),
})
elif request.method == 'POST':
form = FoodForm(request.POST)
if not form.is_valid():
return render(request, 'myapp/home.html', {
'form': form,
})
food = form.cleaned_data['food']
return HttpResponse(food)
テンプレートファイルは↓です。
<form action="/" method="POST">
{% csrf_token %}
{{ form }}
<input type="submit" value="送信" />
</form>
ブラウザで/
にアクセスすると↓のように表示されます。
そして選択肢を選択して送信ボタンをクリックすると、画面にはその選択肢の値が表示されます。
ChoiceFieldの構造
ChoiceField
はdjango.forms.fields
内に定義されています。
ChoiceField
はField
を継承したクラスです。
__init__()
メソッドの構造は↓になります。
def __init__(self, *, choices=(), **kwargs):
...
__init__()
ではkwargs
を親の__init__()
に渡しています。
そのためchoices
を除いた引数の扱いはほとんどField
の仕事になっています。
Field
もdjango.forms.fields
内で定義されています。
Field
の__init__()
は↓のような構造になっています。
def __init__(self, *, required=True, widget=None, label=None, initial=None,
help_text='', error_messages=None, show_hidden_initial=False,
validators=(), localize=False, disabled=False, label_suffix=None):
...
おわりに
今回はDjangoのChoiceField
について見てみました。
選択肢を扱いたい場合にChoiceField
は非常に便利なフィールドです。
🦝 < 選択肢は無限にある
🐭 < 選ぶのも一苦労