Django Wizardでプレビュー画面を作りたい
複数ページからなる入力フォーム画面を作りたいときにはDjangoWizardの出番だ。
基本的な使い方は公式のドキュメントでだいたい分かる。
雑に流れはこんな感じ。
WizardViewを継承したオブジェクトを定義する。
定義したオブジェクトに複数のFormオブジェクトを授ける。
それから全ての入力フォーム画面への入力を終えたときに呼び出されるgoneメソッドの実装を忘れてはいけない。
上記のような下準備をすると複数ページにまたがる入力フォーム画面ができてしまう。
[フォーム画面 A] -> [フォーム画面 B] -> … [フォーム画面 X] -> [goneメソッド]
いいね。
ただ1つ困ることがあった。
プレビュー画面がないのだ。
goneメソッドで各フォームの入力値を受け取ってプレビュー画面を描画することを考えたが、goneメソッドが呼び出されると各入力フォーム画面で入力した値が全て消えてしまう。これは困る。
goneメソッド直前のフォーム画面をプレビュー画面として利用することにした。
プレビュー画面で過去に入力した値を表示するためには、これまで入力してきたFormオブジェクトが必要だ。
get_context_dataメソッドをオーバライドして新たにFormオブジェクト一覧を付与してやればOK。
ドキュメント内では下記のような例があげられてる。
1 2 3 4 5 |
def get_context_data(self, form, **kwargs): context = super(MyWizard, self).get_context_data(form=form, **kwargs) if self.steps.current == 'my_step_name': context.update({'another_var': True}) return context |
stepsの状態に応じて、context(単なる辞書型オブジェクト)にanother_varというキーでTrueという値を追加してる。
これと同じノリで各フォームオブジェクトをリストにしてcontext.updateで追加してやればよさそうだ。
下記のようになった。
1 2 3 4 5 6 7 8 |
def get_context_data(self, form, **kwargs): context = super(MyWizard, self).get_context_data(form=form, **kwargs) if self.steps.current == 'preview': form_list = [] for step in self.steps.all: form_list.append(self.get_form(step, data=self.storage.get_step_data(step), files=self.storage.get_step_files(step)) context.update({'form_list': form_list}) return context |
WizardViewにget_formというメソッドがある。
ここにstepやらstepに紐づいてる入力データや入力ファイルを引数として渡してやるとFormオブジェクトが取得できる。
それをリストに詰め込んで、contextに詰め込んでる。
プレビュー画面用のテンプレート内からは{{ form_list }}
って感じでアクセスできる。
{% for form in form_list %}{% endfor %}などを駆使してイイカンジに表示してやればプレビュー画面が作れるわけ。
ちょっと面倒なので他に楽なやり方があれば知りたいが、情報がなさ過ぎて困ってる。
DjangoPreviewと簡単に組み合わせられたりするのかなー。コード読んでみた感じ親和性なさそう。
336px
336px
関連記事
-
-
PythonでEnumに状態を追加する
この …