微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Django项目中的session存储

参考Django项目中的session存储

一、启用Session

Django项目认启用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这个表

在这里插入图片描述

表结构如下,包括三个数据:键,值,过期时间

在这里插入图片描述

2、本地缓存

存储在本机内存中,如果丢失则不能找回,比数据库的方式读写更快。

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会同时写到redisMysqL中。

3、用户登出注销session

登出调用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删除会同时到redisMysqL删除

4、自定义session内容

定义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值

在这里插入图片描述


获取获取不到了

在这里插入图片描述

五、存储优先级测试

1、登陆并创建key

首先进行登陆生成用户的session,然后调用上面的post接口创建testsession这个key,这个时候redisMysqL中都有存储session。

在这里插入图片描述

在这里插入图片描述

2、将redis中该用户的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缓存中。

在这里插入图片描述


在这里插入图片描述

3、将MysqL中session删除

现在先将MysqL中的session删除

在这里插入图片描述


然后调用get获取key值,可以获取

在这里插入图片描述


但是查看MysqL中的session信息并没有重新写入,说明是先读取的redis缓存中的session信息,如果读取到了则直接返回,不会再去验证MysqL中的。

在这里插入图片描述

然后再调用post接口设置key,报错了,查看后台报错,提示用户请求的session已经被删除了,这个用户可能已经登出了。

在这里插入图片描述


而查看redis中的数据并没有变化,说明在写入是可能是先写入到MysqL,再写入redis缓存,如果MysqL报错了则直接返回了,不会再写入redis

在这里插入图片描述

综上所述,使用混合缓存是,MysqL中的数据是很重要的,如果删除或损坏了,session可能就无法恢复了

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐