1. 程式人生 > >session源碼剖析

session源碼剖析

cache session username 用戶數據 exception get port 登錄 global

session機制采用的是一種在客戶端與服務端之間保持狀態的解決方案,由於采用服務器端保持狀態的方案在客戶端也要保存標識,session機制也要借助於cookie機制達到目的。session保存了客戶的登錄信息,但是不需要把用戶的所有信息都保存在session中,我們只需要讓與用戶數據關聯的信息保存在session中就可以了。

request.session[“user_id”] = 2  # 設置session  關聯id比關聯username好,因為username可能不唯一
request.session.get["user_id"]  # 取session

接下來看源碼:

from django.contrib.sessions.middleware import SessionMiddleware  # 點擊SessionMiddleware看源碼
import time
from importlib import import_module

from django.conf import settings
from django.contrib.sessions.backends.base import UpdateError
from django.core.exceptions import SuspiciousOperation
from django.utils.cache import patch_vary_headers from django.utils.deprecation import MiddlewareMixin from django.utils.http import cookie_date class SessionMiddleware(MiddlewareMixin): def __init__(self, get_response=None): self.get_response = get_response # 這是個空變量,get_response=None engine
= import_module(settings.SESSION_ENGINE) # 用了兩個settings self.SessionStore = engine.SessionStore def process_request(self, request):...def process_response(self, request, response):...

先看這個settings,點擊

from django.conf import global_settings  # 這裏面有global_settings,點擊看源碼

......

settings = LazySettings()
SESSION_ENGINE = django.contrib.sessions.backends.db‘  # 這個文件裏面會看到SESSION_ENGINE

這裏面可與看到SESSION_ENGINE是一條配置信息,這裏默認將session的信息放到djano數據庫裏面的session表裏面。所以我們可以通過這裏面的配置,將session信息放到緩存、文件、Memcache中。另外可以從from django.conf import settings看出,我們這裏引用的settings不僅僅是我們django的settings.py文件還有global_settings.py文件,一共兩套,先找我們常用的settings.py如果找不到,再去global_settings.py文件裏面找。

另外一點值得註意的是:

engine = import_module(settings.SESSION_ENGINE)  
# SESSION_ENGINE = ‘django.contrib.sessions.backends.db‘ 是一個字符串
# import_module("django.contrib.sessions.backends.db") 和 importdjango.contrib.sessions.backends.db 效果是一樣的
# 引入模塊之後,再賦值給 engine,所以優先用自己寫的engine

就接下來看:

class SessionMiddleware(MiddlewareMixin):
    def __init__(self, get_response=None):
        self.get_response = get_response  # 這是個空變量,get_response=None
        engine = import_module(settings.SESSION_ENGINE)  # 用了兩個settings
        self.SessionStore = engine.SessionStore  # 這裏可以看到,因為模塊名是engine,所以SessionStore一定是它裏面的變量名

繼續去看源碼:

from django.contrib.sessions.backends import db  # 點擊db看源碼

可以看到,SessionStore是一個類的名字,self.SessionStore這裏就是一個類名,所有的功能都封裝在SessionStore裏面,非常重要。

class SessionStore(SessionBase):...

走到這裏,__init__這個函數就執行完了。繼續執行process_request方法。

def process_request(self, request):
    session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
    request.session = self.SessionStore(session_key)

先去常用的settings.py文件裏找,這裏找不到,再去global_settings.py裏面找SESSION_COOKIE_NAME,就會看到:

SESSION_COOKIE_NAME = sessionid‘  # 這裏拿到了sessionid



session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)  # 拿到sessin之後進行了一個取的操作,沒有sessionid鍵值對,session_key就是None

所以用戶登陸進來,一定會去取這個cookie,無論是第一次還是第二次登陸,不管cookie是不是空的,都要去取cookie裏面的sessionid這個鍵,如果是第一次登陸肯定沒有sessionid這個鍵,如果是第二次第三次登陸肯定有我給你的這個鍵。

session源碼剖析