FormPreviewを使って確認ページ有りの更新機能を実装する
昨日さわってみたFormPreviewですが、ぱっと見た感じだと更新機能に対応できないように見えたので、いろいろ調べてみました。
以下はFormPreviewでフォームを表示する部分の関数です。
def preview_get(self, request): "Displays the form" f = self.form(auto_id=self.get_auto_id(), initial=self.get_initial(request)) return render_to_response(self.form_template, self.get_context(request, f), context_instance=RequestContext(request))
formのインスタンスを作成するときに、initialを指定できるようです。get_initialは空実装になってます
def get_initial(self, request): """ Takes a request argument and returns a dictionary to pass to the form's ``initial`` kwarg when the form is being created from an HTTP get. """ return {}
更新対象のデータを取得するために、idをパラメータで受け取るようにします。
urls.py
url(r'^update/(?P<id>\d+)/$', AddressUpdatePreview(AddressForm)),
パスに含まれたパラメータはparse_paramsをオーバーライドして取得します。
元々は空実装
def parse_params(self, *args, **kwargs): """ Given captured args and kwargs from the URLconf, saves something in self.state and/or raises Http404 if necessary. For example, this URLconf captures a user_id variable: (r'^contact/(?P<user_id>\d{1,6})/$', MyFormPreview(MyForm)), In this case, the kwargs variable in parse_params would be {'user_id': 32} for a request to '/contact/32/'. You can use that user_id to make sure it's a valid user and/or save it for later, for use in done(). """ pass
self.stateに値を突っ込んでおけば、画面遷移を通して値を取得できます。
FormPreviewをオーバーライドしたクラスの全体はこんな感じ
class AddressUpdatePreview(FormPreview): def parse_params(self, *args, **kwargs): self.state["address_id"] = kwargs["id"] def get_initial(self, request): address = Address.objects.filter(pk=self.state["address_id"]).values()[0] return address def done(self, request, cleaned_data): address = Address.objects.get(pk=self.state["address_id"]) for (key, value) in cleaned_data.items(): setattr(address, key, value) address.save() return redirect(reverse('address_created', args=(), kwargs={}))
これでFormPreviewを使って更新機能が実装できました。