【Django(学習用)コピペ可】ChoiceField choices の値を動的に操作する

※本サイトにはプロモーション・広告が含まれています。

(最終更新月:2021年10月)

「Selectタグ 選択要素を動的な値にしたい!」

「任意の値をフォームへ渡し、選択肢を作りたい!」

と考えている方も多いのではないでしょうか?

当記事では、Django初学者の方向けに

  • Django Form内のChoiceField choicesを動的に操作する

方法をお伝えします

まずは決まった値を選択肢とする方法をカンタンにおさらいし、本題へと進みます

【バージョン情報】

  • OS: Ubuntu 20.10
  • Python: 3.8.10
  • Django: 3.1.4
  • PostgreSQL: 12.7
  • React: 17.0.1

筆者プロフィール

筆者プロフィールアイコン

【現職】プロダクトマネージャー

【副業】ブログ(月間20万PV)/YouTube/Web・アプリ制作

「プログラミング × ライティング × 営業」の経験を活かし、30後半からのIT系職へシフト。現在はプロダクトマネージャーとして、さまざまな関係者の間に入り奮闘してます。当サイトでは、実際に手を動かせるWebアプリの開発を通じて、プログラミングはもちろん、IT職に必要な情報を提供していきます。

【当ブログで紹介しているサイト】

当サイトチュートリアルで作成したデモ版日報アプリ

Django × Reactで開発したツール系Webアプリ

✔人に見せても恥ずかしくないコードを書こう

「リーダブルコード」は、わかりやすく良いコードの定義を教えてくれる本です。

  • 見るからにきれいなコードの書き方
  • コードの分割方法
  • 変数や関数の命名規則

エンジニアのスタンダートとすべき基準を一から解説しています。

何回も読むのに値する本なので、ぜひ手にとって読んでみてください。

決まった値を選択肢とする方法

選択肢とする値が決まっている場合、

CHOICES_TUPLE = (("データベースに保存する名前", "HTML内で表示する文字列"), (.., ..), ....)

とし、CHOICES_TUPLEという選択肢を作成します

ChoiceFieldの引数「choices」にCHOICES_TUPLEを入れることで、

some_field = forms.ChoiceField(choices=CHOICES_TUPLE)

ChoideFieldの選択肢がCHOICE_TUPLEの値になります

好きな値を選択肢にする

大まかな流れは、

  1. views.py内で好きな選択肢を作成する
  2. views.py内のget_form_kwargs関数でforms.pyへ選択肢を渡す
  3. forms.py内で選択肢を受け取り、ChoiceFieldへ割り当てる

となります

【views.py】get_form_kwargs()内

クラスベースビューに備わっているget_form_kwargsメソッドは、フォームへ値を渡す役割を担っています

    def get_form_kwargs(self, *args, **kwargs):
        kwgs = super().get_form_kwargs(*args, **kwargs)
        category_choice = (("choice1", "1"), ("choice2", "2"), ("choice3", "3"))
        kwgs["categories"] = category_choice
        return kwgs

category_choiceという選択肢をお好きに作成してください

今回は決まった値にしていますが、仮にこちらをデータベースから取り出したQuerySetなどにすると保存されている情報により選択肢が変わる「動的な選択肢」となります

kwgs["categories"] = category_choice

とし、forms.pyへ渡します

【forms.py】

class LeadForm(forms.ModelForm):
    category = forms.ChoiceField()

    class Meta:
        model = Lead
        fields = "__all__"

    def __init__(self, categories=None, *args, **kwargs):
        self.base_fields["category"].choices = categories
        super().__init__(*args, **kwargs)

views.pyより渡された値は、__init__メソッド内で処理します

__init__メソッド内で気をつけることは、

  1. 引数でviews.pyから渡された「キー」を受け取ること
  2. self.base_fieldsで、ChoiceFieldを指定しているフィールド名を指定すること
  3. フィールドのchoices属性にviews.pyから受け取った「categories」をパスすること

の3点です

まとめ

以上で、好きな選択肢をテンプレートに反映されることが可能です

前に記述の通りデータベースから保存したデータを選択肢としたり、ランダムな数値などを選択肢としたり、とすることで動的な選択肢を作成することもカンタンにできます

また、views.pyから値を渡さずともforms.py内で処理をすることもできるので自分にとってカンタンな方法で試してみてください!

具体的に動的な選択肢を作成する方法として、ArrayFieldで保存された値を選択肢とする方法をこちらの記事で解説しています↓

タイトルとURLをコピーしました