Django 如何使用会话?原理、配置及使用
1. Django如何使用session
1.1)Session是通过中间件实现的,所以需要先配置MIDDLEWARE
MIDDLEWARE = [
... ...
'django.contrib.sessions.middleware.SessionMiddleware',
... ...
]
1.2)默认的session模块是django.contrib.sessions.model.Session,具体参见
# django/conf/global_settings.py
# The module to store session data
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
# Cache to store session data if using the cache session backend.
SESSION_CACHE_ALIAS = 'default'
源码,因此,您需要在 INSTALLED_APPS 中配置
INSTALLED_APPS = [
... ...
'django.contrib.sessions',
... ...
]
,然后运行 python manage.py migrate
以使安装高效并使用数据库表来存储会话数据。
当前高版本的Django在项目创建和配置后默认使用数据库存储库。如果不想使用session,可以删除以上两个配置
但如果想使用其他方式保存session,则需要显式配置SESSION_ENGINE
等相关配置
2。配置会话模块
2.1。使用数据库存储Session的具体配置请参见上面的介绍。
2.2。使用缓存来存储会话。使用缓存可以提供更好的性能。比如这里使用Redis/Memcached作为缓存
# proj/settings.py
# 先配置CACHE 缓存
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379',
},
'as_session': {
'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache',
'LOCATION': '127.0.0.1:11211',
}
}
上面配置两个缓存的目的是为了说明Django默认的全局配置SESSION_CACHE_ALIAS
默认选择的是‷
‷ 默认当然可以选择其他缓存,比如memcached缓存as_session。此时,您需要显式配置
# proj/settings.py
# Cache to store session data if using the cache session backend.
SESSION_CACHE_ALIAS = 'as_session'
# The module to store session data
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
2.3。使用文件保存会话
# proj/settings.py
# The module to store session data
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
# 默认是 tempfile.gettempdir()
# 一定要保证对应的程序有权限读写
SESSION_FILE_PATH = '/data/proj/file_session.txt'
2.4。使用cookie来存储session
# proj/settings.py
# The module to store session data
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
session模块会使用项目配置SECRET_KEY
是Django内置的加密工具(参见https://docs.djangoproject.com/zh-hans/4.1.1.1) .主题/签名/)
2.5。特殊的cached_db存储session其实是除了上述四种方法之外,还有一种组合方法cached_db
通过阅读源码,发现源码中的
# django.contrib.sessions.backends.cached_db.py
from django.conf import settings
from django.contrib.sessions.backends.db import SessionStore as DBStore
from django.core.cache import caches
KEY_PREFIX = "django.contrib.sessions.cached_db"
class SessionStore(DBStore):
"""
Implement cached, database backed sessions.
"""
cache_key_prefix = KEY_PREFIX
def __init__(self, session_key=None):
self._cache = caches[settings.SESSION_CACHE_ALIAS]
super().__init__(session_key)
... ...
DBStore代码实际上是一个基于数据库的会话存储。那么这里cached_db继承自DBStore,然后新增的self._cache
是一种基于缓存的Session存储方式。
在视图中使用会话
可以直接在视图中使用request.session
,这基本上是HttpResquest对象的会话属性。
为什么可以直接使用?主要是通过SessionMiddleware来体现
# django/contrib/sessions/middleware.py
from django.utils.deprecation import MiddlewareMixin
class SessionMiddleware(MiddlewareMixin):
# RemovedInDjango40Warning: when the deprecation ends, replace with:
# def __init__(self, get_response):
def __init__(self, get_response=None):
super().__init__(get_response)
engine = import_module(settings.SESSION_ENGINE)
self.SessionStore = engine.SessionStore
def process_request(self, request):
session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
# 核心代码
request.session = self.SessionStore(session_key)
,然后所有的会话引擎都继承自SessionBase
。这个类提供了一些标准的字典方法
# django/contrib/sessions/backends/base.py
class SessionBase:
def __getitem__(self, key):
# val = request.session[key]
... ...
def __setitem__(self, key):
# request.session[key] = val
... ...
def __delitem__(self, key):
# del request.session[key]
... ...
def __contains__(self, key):
# key in request.session
... ...
def get(self, key, default=None):
# val = request.session.get('key', 'default_val')
... ...
def pop(self, key, default=__not_given):
# val = request.session.get('key', 'default_val')
... ...
... ...
,还有很多像set_expiry()\cycle_key()等方法,如果有兴趣可以自己查看源码
吗?实际使用过程中有几个注意事项
1。强烈建议使用 JSON 序列化,即使是自定义序列化。这就是 Django 的顺序会话默认的使用方式。
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'
2。 request.session 使用常见的Python字符串作为字典键
。不要使用以下划线开头。这是保留给 Django 内部使用的
3。不要覆盖 request.session 只需将其用作常规 Python 字典即可。
使用示例
def login(request):
user = User.objects.get(username=request.POST['username'])
if user.check_password(request.POST['password']):
# 登录成功之后,保存用户ID到session中,用于后续判断
request.session['user_id'] = user.id
return HttpResponse("You're logged in.")
else:
return HttpResponse("Your username and password didn't match.")
在视图外使用会话
基础是在自己的代码中导入所需的会话存储模块,建议使用import_module方法,
# 直接导入
from django.contrib.sessions.backends.db import SessionStore
s = SessionStore()
# 建议 import_Module方式
>>> from importlib import import_module
>>> from django.conf import settings
>>> SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
>>> s = SessionStore()
>>> s
<django.contrib.sessions.backends.db.SessionStore object at 0x102ac6160>
>>> s['username'] = 'James'
>>> s.session_key
>>> s.create()
>>> s.session_key
'v75esxsbrye4efrl3tppsp6w443jawq5'
>>> s2 = SessionStore(session_key='v75esxsbrye4efrl3tppsp6w443jawq5')
>>> s2['username']
'James'
>>> s2.session_key
'v75esxsbrye4efrl3tppsp6w443jawq5'
扩展介绍-会话持久化
在会话V相关配置中,SESSION_EXPIRE_AT_BROWSER_CLOSE
用于控制会话是否在上使用持久会话♷或❙♷ • 当 _EXPIRE_AT_BROWSER_CLOSE=True 时会话 Django当使用
当然,除了上面的全局变量来控制会话过期之外,你还可以显式地使用 浏览器长度 ♷ 时,表示浏览器关闭,会话自动过期
表示浏览器关闭,会话通过 SESSION_COOKIE_AGE
过期后request.session
中的 set_expiry() 在每个会话级别进行覆盖
扩展简介 - 清理会话
1。如果session存储在db或者文件中,那么Django不提供自动删除过期session的功能,需要调整过期session的定期删除。
建议使用Django提供的内置clearesessions命令
2。如果使用缓存或cookie,则具有过期后自动删除的功能。无需人工干预。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。