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を代入するように修正しました。
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
コメントでご指摘をいただき、もっと簡単にできることがわかりました。
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なオブジェクトを渡すことで更新されるようになりました。
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)
これでもできます!