【django】 sessionてなに?どう使う?

Django

インターネットにおけるsessionからdjangoのsessionに関してを書いていきます。

sessionとは

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

このsessionはサイト間を移動しても保持続けたり、ある一定以上の時間が経つと消えたり、webブラウザを閉じると消えたりして、どれほど保持するかはそのサイトで決まっています。

django の session の使い方

djangoでもsessionはあります。
djangoでsessionを使用する際は設定する必要があります。
設定でsessionを有効化する必要があるのです。

といってもデフォルトで有効化されているはずなので、
settings.pyが下記のようになっているか確認しましょう。
もし、settings.pyの以下の部分が変更されてしまっていた場合は、これらのコードを追加しましょう。

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

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

これで設定部分は完了です。
settings.pyで設定が完了できたらsessionは使えるようになります。
次にviews.pyで実際にsessionを使っていきます。

django views.pyでのsessionの使い方

views.pyでsessionを使用する場合、request.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秒設定となる。

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

sessionの使い道

では、実際にsessionはどこでどのように使うのか。
それはsessionの特徴

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

から考えると入力データの使い回しなどではないでしょうか。
ということで、フォームで入力されたデータを保持したまま
次のページで入力データを確認するサンプルを作成します。

sessionの使い道サンプル

forms.pyにはTestFormという名前のフォームクラスを作ります。
中身は簡単に、名前と年齢を入力するだけです。

from django import forms 

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

urls.pyには入力のURLとして ‘input’ と 確認用としての ‘confirm’ をつくります。

from django.urls import path
from . import views

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

views.pyのinputでは’GET’か ‘POST ‘か判断して処理を変えています。
GETの場合は、入力中のデータが無いか確認をしています。
POSTはバリデートして確認用の ‘confirm’ に移動させます。

confirmではsession中にデータがあるか確認を行い、そのデータを画面表示させます。
そのあと画面上のボタン「送信」を押すと’POST’で届き、何かしら処理ができるようになります。

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})

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
ここで入力データの確認が可能です。

以上です。

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