Django で view から Form オブジェクトに値を渡す : kwargs活用
args, kwargs が良くわかってなかったので苦労した話。python2.7.x と Django1.8.xでの確認です。
Formオブジェクトに渡すときには
Formオブジェクトを生成するときに、GET パラメーターを渡したいと考えたが発端。あちこち参照して、一つに落ち着きました。
views.py:
class TestFormView(FormView): template_name = 'testform.html' form_class = TestForm success_url = reverse_lazy('index')
forms.py
class TestForm(forms.Form): name = forms.CharField(max_length=10) def __init__(self, *args, **kwargs): super(TestForm, self).__init__(*args, **kwargs)
kwargs で渡し、 pop で取得
これが一番だと思う。
views で こんな感じで渡して:
class TestFormView(FormView): def get_form_kwargs(self): kwargs = super(TagEditView, self).get_form_kwargs() kwargs['user'] = self.request.user return kwargs
Form で pop を使って受け取る:
class TestForm(forms.Form): def __init__(self, *args, **kwargs): self.user = kwargs.pop('user') super(TestForm, self).__init__(*args, **kwargs)
この方法だと pop した段階で kwargs から対象の値が削除されるので、その後の親クラス呼ぶときなどに気を使わなくてもいい。
FormViewに用意されてる get_form_kwargs という名称からもよろしげじゃないですかね?
kwargs で渡し、 直接参照
渡し方は、前と同じなのです。
Form で 直接指定して受け取る:
class TestForm(forms.Form): def __init__(self, *args, **kwargs): self.user = kwargs['user'] super(TestForm, self).__init__(*args, **kwargs)
この方法だと super.__init__ 側で、 user なんて知らんでとエラーが出る。Dictionary型としらず、popを使うことを知らなかった時に陥りました。
引数を増やし、直接参照
これでも渡せるけど、あまり好きじゃないかも。
views で form生成時に引数として渡して:
class TestFormView(FormView): def get(self, request, *args, **kwargs): form_class = self.get_form_class() form = form_class(user=request.user)
Form で 直接参照して受け取る:
class TestForm(forms.Form): def __init__(self, user, *args, **kwargs): self.user = user super(TestForm, self).__init__(*args, **kwargs)
親クラス.__init__ と引数が異なるのが、なんとなく気持ち悪いような。。。
その他
感想
そもそも args, kwargs の事を、これまでに考えてなかったのがいかんかった。
こんな分類だと、今回理解。
__init__ の引数 | (勝手な)解釈 | __init__内で使うときに型 | |
*args | ARGumentS : 引数 | Tuple型 | |
**kwargs | KeyWordARGumentS : キーワード型の引数 | Dictionary型 |
だから kwargs.pop なんてつかえるのですね。
今回のことがあり、PyCharmのようなHelpが用意に使えるIDEを検討したくなりました。知識不足を支援してくれそうな感じがして。。