読者です 読者をやめる 読者になる 読者になる

AWS / PHP / Python ちょいメモ

amazon web service , PHP, Python を使ったときのメモ。日本語でググってもわからなかった事を中心に。

Django で view から Form オブジェクトに値を渡す : kwargs活用

Django python

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を検討したくなりました。知識不足を支援してくれそうな感じがして。。