合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
# 状态保持 ## 状态保持 * http协议是无状态的:每次请求都是一次新的请求,不会记得之前的通信的状态 * 客户端与服务端的一次通信,就是一次会话 * 实现状态保持的方式,在客户端或服务器端存储于会话有关的数据 * 储存方式包括cookie、session、会话一般指session对象 * 使用cookie,所有数据存储在客户端,注意不要储存敏感信息 * 推荐使用session方式,所有数据存储在服务器端,在客户端cookie中存储session\_id * 状态保持的目的是在一段时间内跟踪请求者的状态,可以实现跨页米娜访问当前请求者的数据 * 注意:不同的请求者之间不会共享这个数据,与请求者一一对应 ## 启用session * 使用django-admin startproject创建的项目默认启用 * 在settings.py文件中 * 在INSETALLED\_APPS列表中添加 ```text INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', # 添加 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'myapp', ] 在MIDDLEWARE_CLASSES列表中添加 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', #添加 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ``` * 禁用会话:删除上面的指定的两个值,禁用会话将节省一些性能消耗 ### 使用session * 启用会话后,每个HttpRequest对象将具有一个session,是一个类字典对象 * get\(key,default=None\):根据键获取会话的值 * clear\(\):清除所有会话 * flush\(\):删除当前的会话数据并删除会话Cookie * del request.session\['memeber\_id'\]:删除会话 * 在views.py文件创建视图 ```text from django.shortcuts import render,redirect from django.urls import reverse def index(request): name = request.session.get('name',default="游客") print(request.session.get('name'),'2') return render(request,"myapp/index.html",{'name':name}) def login(request): return render(request,'myapp/login.html') def login_handle(request): request.session['name'] = request.POST['name'] print(request.POST['name']) return redirect(reverse("myapp:index")) def logout(request): request.session.flush() return redirect(reverse('myapp:index')) ``` * 配置url ```text 主url: from django.conf.urls import include,url url(r'',include('myapp.urls',namespace='myapp')), 应用url: from django.conf.urls import url from . import views url(r'login/$', views.login, name='login'), url(r'login_handle/$', views.login_handle, name='login_handle'), url(r'logout/$', views.logout, name='logout') ``` * 创建模板index.html ```text <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>session会话</title> </head> <body> <h1>Hello,{{ name }}</h1> <hr/> <a href="{% url 'myapp:login' %}">登录</a> <a href="{% url 'myapp:logout' %}">登出</a> </body> </html> ``` * 创建模板login.html ```text <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form method="post" action="{% url 'myapp:login_handle' %}"> 姓名: <input type="text" name="name"/><br /> <input type="submit" value="value"/> </form> </body> </html> ``` ## 会话过期时间 * set\_expiry\(value\):设置会话的超时时间 * 如果没有指定,则两个星期后过期 * 如果value是一个整数,会话将在values秒没有活动后过期 * 如果value是一个imedelta对象,会话将在当前时间加上这个指定的日期/时间过期 * 如果value为0,name会话的cookie将在用户的浏览器关闭时过期 * 如果value为None,name会话永不过期 * 修改视图中login\_handle函数,查看效果 ```text def login_handle(request): request.session['name'] = request.POST['name'] print(request.POST['name']) # request.session.set_expiry(10) # request.session.set_expiry(timedelta(days=5)) # request.session.set_expiry(0) # request.session.set_expiry(None) return redirect(reverse("myapp:index")) ``` ## 存储session * 使用存储会话的方式,可以使用settings.py的SESSION\_ENGINE项指定 * 基于数据库的会话:这是django默认的会话存储方式,需要添加django.contrib.session到的INSTALLED\_APPS设置中,运行manage.py migrate在数据库中安装会话表,可显示指定为 ```text SESSION_ENGINE='django.contrib.sessions.backends.db' ``` * 基于缓存的会话:只存在本地内在中,如果丢失则不能找回,比数据库的方式读写更快 ```text SESSION_ENGINE='django.contrib.sessions.backends.cache' ``` * 可以将缓存和数据库同时使用:优先从本地缓存中获取,如果没有则从数据中获取 ```text SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' ``` ## 使用Redis缓存session * 安装 django-redis、django-redis-session * pip install django-redis * pip install django-redis-sessions * 修改settings中的配置 ```text # 缓存 CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } } } SESSION_ENGINE = "django.contrib.sessions.backends.cache" SESSION_CACHE_ALIAS = "default" REDIS_TIMEOUT=7*24*60*60 CUBES_REDIS_TIMEOUT=60*60 NEVER_REDIS_TIMEOUT=365*24*60*60 ``` * 测试缓存是否成功 ```text 输入交互命令:python manage.py shell In [1]: from django.core.cache import cache #引入缓存模块 In [2]: cache.set('v', '555', 60*60) #写入key为v,值为555的缓存,有效期30分钟 Out[2]: True In [3]: cache.has_key('v') #判断key为v是否存在 Out[3]: True In [4]: cache.get('v') #获取key为v的缓存 Out[4]: '555' ``` * redis数据库更多详细:[http://django-redis-chs.readthedocs.io/zh\_CN/latest/\#cache-backend](http://django-redis-chs.readthedocs.io/zh_CN/latest/#cache-backend) * 管理redis的命令 ```text 下载地址:https://github.com/MicrosoftArchive/redis/releases 启动:net start redis 停止:net stop redis 重启:net restart redis 使用客户端连接服务器:redis-cli keys *:查看所有的连接 get name:获取指定键的值 del name:删除指定名称的键 ```