【django】 sessionてなに?どう使う?【徹底解説】

スポンサーリンク
Django

djangoにおけるsessionについて解説します。

本記事は「sessionってたまに聞くけど、なにか分からない」、「sessionを使いこなすと便利?」と悩んでいる方に向けて

djangoのsessionに関して解説・使い方を紹介していきます。

sessionを伝える上でdjangoだけではなく、インターネット上のsessionに関しても触れていきます。

本記事を読み終えると、sessionに関してどういうものか理解でき、sessionを使用できるようになります。

ではまず、sessionとは何かを解説していきます。

sessionとは

sessionに関してざっくりと説明していきます。

sessionは「あるwebサイトにアクセスしてから一連の処理やデータ保持」することを指します。

つまり、sessionの中にはデータが入っているということです。

このsession内部のデータはどれほど保持するかは、訪問したサイトごとで決まっています。

sessionのデータ保持やデータ消失に関して、一例を上げると、以下のような特徴があります。

  • 違うサイト間を移動してもsessionの内部データ保持を続ける
  • 同じサイトである一定以上の時間が経つとsessionの内部データが消える
  • webブラウザを閉じると同時にsession内部のデータが消える

というようにsessionのデータ保持・消失はバラバラです。

これではユーザー側にはどのタイミングでsessionのデータが消えたかが分からないですが、開発者側にはカスタマイズしやすく、セキュリティも高くなります。

django の session の使い方

まず、djangoでもsessionはあります。

djangoでsessionを使用する際は設定する必要があり、sessionを有効化しなければいけません。

といってもデフォルトで有効化されているはずなので、settings.pyが下記のようになっているか確認しましょう。

もし、settings.pyの以下の部分が変更されてしまっていた場合は、下記のコードを追加しましょう。

INSTALLED_APPS = [
    :
    'django.contrib.sessions',
    :
]

MIDDLEWARE = [
    :
'django.contrib.sessions.middleware.SessionMiddleware',
    :
]

このsettings.pyのコードであればOKです。sessionは使えるようになります。

次にviews.pyで実際にsessionを使っていきます。

django views.pyでのsessionの使い方

djangoでsessionを使用する場合、views.pyでsessionを操作するコードを書きます

views.pyでsessionを使うには、request.sessionを使います。

これはrequestオブジェクトの中に、sessionが入っているため、request.sessionでないと操作ができないためです。

また、sessionの使い方は、pythonの辞書型を扱うのとほぼ同じです。

以下に操作するコードを書きます。
それぞれ、sessionへの保存・sessionの取得・sessionの中身の一部削除・session中身を全削除です。

最後にsessionのデータ保持をする期限を設定する関数を書いてあります。

#保存
    request.session['s'] = 'test for session'
#値の取得
    request.session.get('s') #出力は'test for session'
#値の一部削除
    request.session.pop('s')
#値の全削除
    request.session.clear()
#セッション切の期限を設定
    request.session.set_expiry(value)
#期限設定は秒単位で設定でき、valueは整数の値を入れる。
#例えば、request.session.set_expiry(5)で5秒設定となる。

いかがでしょうか?pythonの辞書型とほぼ同じであるため

そこまでsessionを使うのは難しくないですね。

sessionの使い道

では、実際にsessionはどこでどのように使うのか。

それは以下のようなsessionの特徴

  • サイト訪問時にsessionがつく
  • 訪問者ごとにsessionを持つ
  • データの保持が可能

から考えると、「入力データの使い回し」が想定される使用パターンではないでしょうか。

ということで、フォームで入力されたデータを保持したまま、次のページで入力データを確認するサンプルを作成します。

sessionの使い方のサンプル

では、sessionの使い方のサンプルを紹介します。用途は「入力データの使い回し」です。

最初にforms.pyをいじっていきます。

forms.pyには、TestFormという名前のフォームクラスを作ります。

TestFormの中身は簡単で、「名前」と「年齢」を入力するだけのフォームです。

from django import forms 

class TestForm(forms.Form):
    Name = forms.CharField()
    Age = forms.IntegerField()

次に、urls.pyを作成していきます。

urls.pyには入力用ページのURLとして 「input」 と、 確認用ページのURLとしての「confirm」 をつくります。

from django.urls import path
from . import views

urlpatterns = [
    path('input/', views.input, name='input'),
    path('confirm/', views.confirm, name='confirm'),
]

次にviews.pyを入力していきます。

views.pyの関数ビューの「input」では最初のif文で「GET」か 「POST 」か判別します。

その判別次第で、その後の処理を変えています。


GETの場合は、入力中のデータが無いか確認をし、POSTではバリデートして確認用のページの関数ビュー「confirm」 に移動させます。

関数ビューの「confirm」では、session中にデータがあるか確認を行います。

sessionの内部にデータがあると、そのデータを画面表示させます。

そのあと画面上のボタン「送信」を押すとrequest.methodの「POST」で送信をします。

本コードでは何もしませんが、「POST」で届いたことで何かしら処理ができるようにカスタマイズしましょう。

長々と説明しましたが、views.pyのコードです。

from django.shortcuts import render, redirect
from .forms import TestForm

def input(request):
    if request.method == 'GET':
        if request.session: #入力中のデータがあれば、ここでformに反映
            form = TestForm(request.session.get('a'))
        else:
            form = TestForm()
    else: # 入力してPOSTで送信した場合
        form = TestForm(request.POST)
        if form.is_valid(): #バリデーションを通した後のデータをsession['a']に
            request.session['a'] = request.POST
            return redirect('confirm')
    context = {'form': form}
    return render(request, 'input.html',{'form':form})

def confirm(request):
#session中にデータがあれば再度formに反映し、確認用に表示
    if request.session: 
        data = request.session.get('a')
        form = TestForm(data)
#確認表示し、問題なければ'POST'で処理に回す。
    if request.method == 'POST':
        data = request.session.get('a')
        request.session.clear() 
        form = TestForm(data)
        if form.is_valid():
        # 今回はデータ登録などしない
        # データ登録の場合はここに記述
            return redirect('input')
    return render(request, 'confirm.html', {'form':form, 'data':data})

ちょっと分かりにくいかもしれません。

その時は自力でコードを書いてみると少しずつ理解できるようになります。

続いて、HTMLなどのテンプレートを書いていきます。

関数ビュー「input」で表示されるテンプレート(input.html)です。bootstrapのCSSを使用しています。

  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
    <title>input</title>
  </head>
  <body>
    <form action="" method="POST"></br>
      名前:{{ form.Name }}</br>
      年齢:{{ form.Age }}</br>
      {% csrf_token %}
      <button type="submit" class="btn btn-primary btn-lg">送信</button>
    </form>
  </body>

次に、確認用の関数ビュー「confirm」のテンプレート(confirm.html)です。
こちらもbootstrapのCSSを使用しています。

  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
    <title>confirm</title>
  </head>
  <body>
    <div class="form-group">
      <div>データ確認用</div>
        <div>Name : {{ data.Name }}</div>
        <div>Age : {{ data.Age }}</div>
    </div>
    <a href="{% url 'input' %}" class="btn btn-primary btn-lg">戻る</a>
    <hr>
    <form action="" method="POST">
        <button type="submit" class="btn btn-primary btn-lg">送信</button>
        {% csrf_token %}
    </form>
  </body>

以上の記述で、以下の画像にあるような感じになると思います。

input.html
ここでデータ入力ができます。

confirm.html
ここで入力データの確認が可能です。

長々となりましたが、以上でsessionの使い方をおわります。

タイトルとURLをコピーしました