4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Django の Form Class でセッション情報を利用する

Last updated at Posted at 2021-01-22

概要

フォームのバリデーションを行う際にセッション情報を使いたかったのですが、Django のフォームクラスではリクエストオブジェクトを参照することができません。
セッション情報をコンテキストとしてフォームの hidden 属性で渡したりできますが、、いかんせん格好悪い。

ということで、フォームクラスのメソッドをオーバーライドしてリクエストオブジェクトを渡す方法を紹介します。

検証環境は Python 3.8, Django 3.1.1 です。

forms.py

フォームクラスはデフォルトのキーワード引数として initial や data といったパラメータしか受け取れません。
なので、__init__ メソッドをオーバーライドして、フォームのインスタンス生成時に request パラメータを引数として受け取るようにします。
https://github.com/django/django/blob/master/django/forms/forms.py#L64

forms.py
class MyForm(forms.form):

    def __init__(self, request, *args, **kwargs):
        self.request = request
        super(MyForm, self).__init__(*args, **kwargs)     

views.py

フォームクラスで request をインスタンス引数として受け取るようにしたので、ビュー側でフォームインスタンスを生成する際にリクエストオブジェクトを渡すようにします。

関数ビュー

シンプルにリクエストオブジェクトを引数で渡せばOK。

views.py
def my_form_view(request):
    form = MyForm(request=request, data=request.POST)

クラスビュー

FormView の継承元である FormMixin には、フォームインスタンス生成時にキーワード引数として渡す値を指定するための get_form_kwargs() というメソッドがあります。initial や data といったパラメータを渡します。
https://github.com/django/django/blob/3.0/django/views/generic/edit.py#L35

このメソッドをオーバーライドして、ビュー側から request データを kwargs としてフォームインスタンスに渡すようにします。

views.py
class MyFormView(FormView):
    form_class = MyForm

    def get_form_kwargs(self):
        kwargs = super(MyFormView, self).get_form_kwargs()
        kwargs['request'] = self.request
        return kwargs

これでフォームクラスでもリクエストオブジェクトを参照できるようになりました。

あとは、clean メソッドなどで self.request.session.get('foo') のようにしてセッション情報を取得できます!

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?