参考Django项目中的session存储
一、启用SessionDjango项目默认启用Session。
可以在settings.py文件中查看,如图所示
如需禁用session,将上图中的session中间件注释掉即可。
在settings.py文件中,可以设置session数据的存储方式,可以保存在数据库、本地缓存等。
1、存在在默认数据库中默认存储在数据库中,如下设置可以写,也可以不写,这是默认存储方式。
SESSION_ENGINE='django.contrib.sessions.backends.db'
django.contrib.sessions.backends.db会使用DATAbaseS 设置的数据库,例如
DATAbaseS = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 连接数据库的类型
'NAME': 'luckybaseline', # 数据库名
'HOST': '127.0.0.1', # 数据库主机
'PORT': 3306,
"USER": 'root',
'PASSWORD': '123456',
}
}
数据库中会创建django_session这个表
表结构如下,包括三个数据:键,值,过期时间
存储在本机内存中,如果丢失则不能找回,比数据库的方式读写更快。
SESSION_ENGINE='django.contrib.sessions.backends.cache'3 混合存储
优先从缓存中存取,如果没有则从数据库中存取。
SESSION_ENGINE='django.contrib.sessions.backends.cached_db'4、redis 缓存
在settings.py文件中SESSION_ENGINE开启缓存,并设置CACHES地址为redis
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
SESSION_CACHE_ALIAS = "default"
三、Session操作
通过HttpRequest对象的session属性进行会话的读写操作。
1、以键值对的格式写session。request.session['键']=值2、根据键读取值。
request.session.get('键',默认值)
3、清除所有session,在存储中删除值部分。
request.session.clear()4、清除session数据,在存储中删除session的整条数据。
request.session.flush()5、删除session中的指定键及值,在存储中只删除某个键及对应的值。
del request.session['键']6、设置session的有效期
request.session.set_expiry(value)
- 如果value是一个整数,session将在value秒没有活动后过期。
- 如果value为0,那么用户session的cookie将在用户的浏览器关闭时过期。
- 如果value为None,那么session有效期将采用系统默认值,默认为两周,可以通过在settings.py中设置SESSION_cookie_AGE来设置全局默认值。
# cookie过期时间设为30天 SESSION_cookie_AGE = 60 * 60 * 24 * 30四、实践 1、缓存设置,我这里使用混合存储优先从redis中取
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
SESSION_CACHE_ALIAS = "default"
2、用户登录创建session
首先访问登陆的接口,使用session的前提是用户有进行登陆,接口里调用django的login函数会为用户创建session。这里登陆接口不再描述。
# 如果认证成功,判断user表中是否存在该用户 user = User.objects.filter(username=email) # 如果用户存在,则设置session if user.exists(): login(request, user[0])
查看redis中有为用户创建key
查看mysql中django_session表中为用户创建了一条新的记录
说明设置混合存储后,session会同时写到redis和mysql中。
登出调用django的logout函数
#登陆示例
def post(self,request):
username= request.user.username
#print(username)
logout(request)
return Response({"message":"退出成功","username":username},status=status.HTTP_200_OK)
查看redis,刚才那个key已经没了
查看mysql,刚才那条记录也没了
说明设置混合存储后,session删除会同时到redis和mysql中删除。
定义get post delete三个接口来定义session
class TestSessionAPIView(APIView):
def get(self,request):
print(request.session.get("testsession"))
return Response(request.session.get("testsession"))
def post(self,request):
request.session['testsession']="23333"
return Response("post test interface")
def delete(self,request):
del request.session["testsession"]
return Response("delete test interface")
首先请求post接口,创建session的testsession这个key值
然后请求get接口,获取session的key值
然后调用delete接口,删除刚才创建的key值
再获取就获取不到了
首先进行登陆生成用户的session,然后调用上面的post接口创建testsession这个key,这个时候redis和mysql中都有存储session。
127.0.0.1:6379> key * (error) ERR unknown command `key`, with args beginning with: `*`, 127.0.0.1:6379> keys * 1) "_kombu.binding.celeryev" 2) "_kombu.binding.default" 3) ":1:django.contrib.sessions.cacheavh5lzcneh0ydg5k97lsqykfpn90oaoy" 4) "_kombu.binding.celery" 5) "_kombu.binding.app_task1" 6) ":1:django.contrib.sessions.cached_dbp6i3ex1tgup92m8tdwptvvhuaq22stlb" 7) "_kombu.binding.app_task2" 8) "_kombu.binding.celery.pidbox" 127.0.0.1:6379> del :1:django.contrib.sessions.cached_dbp6i3ex1tgup92m8tdwptvvhuaq22stlb (integer) 1 127.0.0.1:6379> get :1:django.contrib.sessions.cached_dbp6i3ex1tgup92m8tdwptvvhuaq22stlb (nil)
然后再访问get接口,获取testsession这个key值,可以获取到,并且redis中的session数据又重新生成了。
说明当redis缓存中没有session时,会到mysql中获取,如果获取到了,还会将session重新写入到redis缓存中。
现在先将mysql中的session删除
然后调用get获取key值,可以获取到
但是查看mysql中的session信息并没有重新写入,说明是先读取的redis缓存中的session信息,如果读取到了则直接返回,不会再去验证mysql中的。
然后再调用post接口设置key,报错了,查看后台报错,提示用户请求的session已经被删除了,这个用户可能已经登出了。
而查看redis中的数据并没有变化,说明在写入是可能是先写入到mysql,再写入redis缓存,如果mysql报错了则直接返回了,不会再写入redis。
综上所述,使用混合缓存是,mysql中的数据是很重要的,如果删除或损坏了,session可能就无法恢复了



