LoginSignup
7
4

More than 5 years have passed since last update.

DjangoのMultipleChoiceFieldでchoicesが更新されない

Last updated at Posted at 2017-01-04

Django:1.10

以下の記事を書いた後、「追記 2016/11/26」に書いた問題を見つけました。

DjangoでIN演算子を使ったクエリを生成する方法
http://qiita.com/nakkun/items/86a94e65fe6785325f54

MultipleChoiceFieldで著者を選択する入力フィールドを作成する際に、データベースから選択できる著者一覧を取得してchoicesに渡したのですが、著者を追加してもサーバ再起動しないと画面に反映されません。

Viewで代入することはできますが、FormのことはFormにやらせたい。

まだPythonのclassは勉強していなかったので、アプリケーションスコープになるからなのかなとなんとなく思っていました。

年末年始にPython本を読み進めてみると、なるほど、classオブジェクト生成時に値が代入されるからですね。
つまり、Javaでいうstaticフィールドになるわけですね。

なので、インスタンス生成時にchoicesを代入するように修正しました。

forms.py
class SearchForm(forms.Form):

    author = forms.MultipleChoiceField(label='著者', widget=forms.CheckboxSelectMultiple, required=False)

    def __init__(self, param):
        forms.Form.__init__(self, param)
        self.fields['author'].choices = [(author.id, author.name) for author in Author.objects.all()]

これで、ブラウザリロードだけで著者追加が反映されるようになりました。

追記 2017/01/09

コメントでご指摘をいただき、もっと簡単にできることがわかりました。

forms.py
class SearchForm(forms.Form):

    author = forms.ModelMultipleChoiceField(
        label='著者', widget=forms.CheckboxSelectMultiple, required=False,
        queryset=Author.objects.all(), to_field_name='name')

これだけでできます!

追記 2017/01/11

さらにコメントいただきました。
ModelMultipleChoiceFieldを使わなくても、choicesにcallableなオブジェクトを渡すことで更新されるようになりました。

forms.py
class SearchForm(forms.Form):

    author = forms.MultipleChoiceField(
        label='著者', widget=forms.CheckboxSelectMultiple,
        choices=lambda: [(author.id, author.name) for author in Author.objects.all()], required=False)

これでもできます!

7
4
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4