こんばんはエンジニアの眠れない夜です。
以前はForms.pyを編集してフォームの関連テーブルの選択をカスタマイズする方法をご紹介しました。
しかし、もうちょっと使い勝手のいい方法を見つけたので共有です。
フォームにフィルターをかけるのはget_context_data()が便利!
クラスベースビューを使っているとget_context_data()は非常に柔軟でいろんな事ができるのでとても重宝します。
そのget_context_data()がセレクトフォームにフィルターをかける時にも大活躍します。
まずはフォームを編集したいViewに下記のコードを追加してください。
※ クラスベースビューを使用している前提です。
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
print(context['form'].fields)
return context
既にget_context_data()を実装している場合はprint(context['form'].fields)
を追加すれば大丈夫です。
例えばフォームにusernameとemailが設定されている場合は下記のようにプリントされます。
OrderedDict([('username', ), ('email', ),])
※ 読みやすさのため省略しています。
つまり、form_classで指定したフォームを取得することができました。後は煮るなり焼くなり自由にすればOKです。
これだけだとピンとこない方もいると思うので、使い方を紹介します。
get_context_data()でformを編集する方法
フォームのフィールドを取得するにはこんな感じで取得します。
context['form'].fields['username']
context['form'].fields['email']
例としては微妙なのですがUserがBookを関連テーブルとして持っていた場合、下記のようにquerysetに代入できます。
context['form'].fields['book'].queryset = Book.objects.filter()
Book.objects.filter()の部分で自分がかけたいフィルターをかければユーザーに応じて選択できるBookに制限をかけることができます。
まとめ
- クラスベースビューのget_context_data()でformが編集できる。
- context[‘form’].fields[‘NAME’]でフィールドを取得できる。
- context[‘form’].fields[‘NAME’].querysetでセレクトフォームにフィルターをかけられる。
結論、get_context_data()は何でもできる凄いやつってことです。
Forms.pyでは利用できないパラメータなどもget_context_data()の中なら全部使えるので好き放題Formを編集できるというわけです。
便利だからといって何でもかんでもget_context_data()でやってしまうとコードが汚くなるので、装飾などもともとForms.pyでできることはそっちに書いて、こねくり回したい時にget_context_data()を使うようにしましょう。
※ 間違っているところなどありましたらご指摘いただけますと幸いです。
[…] [Django]セレクトフォームをフィルター(カスタマイズ)する方法 […]