浏览器请求服务器是无状态的。无状态指一次用户请求时,浏览器、服务器无法知道之前这个用户做过什么,每次请求都是一次新的请求。无状态的应用层面的原因是:浏览器和服务器之间的通信都遵守HTTP协议。根本原因是:浏览器与服务器是使用Socket套接字进行通信的,服务器将请求结果返回给浏览器之后,会关闭当前的Socket连接,而且服务器也会在处理页面完毕之后销毁页面对象。
有时需要保持下来用户浏览的状态,比如用户是否登录过,浏览过哪些商品等。 实现状态保持主要有两种方式:

获取值
使用request.COOKIE[‘res’]
赋值
使用response.set_cookie(‘res’, res, max_aeg, expires)
对于敏感、重要的信息,建议要储在服务器端,不能存储在浏览器中,如用户名、余额、等级、验证码等信息。
开启项目中的中间件默认开启
打开settings.py文件,在项MIDDLEWARE_CLASSES中启用Session中间件。默认开启

问:所有请求者的Session都会存储在服务器中,服务器如何区分请求者和Session数据的对应关系呢?
答:在使用Session后,会在Cookie中存储一个sessionid的数据,每次请求时浏览器都会将这个数据发给服务器,服务器在接收到sessionid后,会根据这个值找出这个请求者的Session。
结果:如果想使用Session,浏览器必须支持Cookie,否则就无法使用Session了。
存储Session时,键与Cookie中的sessionid相同,值是开发人员设置的键值对信息,进行了base64编码,过期时间由开发人员设置。
打开test3/settings.py文件,设置SESSION_ENGINE项指定Session数据存储的方式,可以存储在数据库、缓存、Redis等。
存储在数据库中,如下设置可以写,也可以不写,这是默认存储方式。(需要连接数据库并且已经存在对应的存放session信息的表)
SESSION_ENGINE='django.contrib.sessions.backends.db'
存储在缓存中:存储在本机内存中,如果丢失则不能找回,比数据库的方式读写更快。
SESSION_ENGINE='django.contrib.sessions.backends.cache'
混合存储:优先从本机内存中存取,如果没有则从数据库中存取。
SESSION_ENGINE='django.contrib.sessions.backends.cached_db'
以键值对的格式写会话。
request.session['键']=值
根据键读取值。
request.session.get('键',默认值)
清除所有会话,在存储中删除值部分。
request.session.clear()
清除会话数据,在存储中删除会话的整条数据。
request.session.flush()
删除会话中的指定键及值,在存储中只删除某个键及对应的值。
del request.session['键']
设置会话的超时时间,如果没有指定过期时间则两个星期后过期。
request.session.set_expiry(value)
将服务器端的session信息保存到数据库的相关配置
安装包。
pip install django-redis-sessions
修改test3/settings文件,增加如下项:
SESSION_ENGINE = 'redis_sessions.session'
SESSION_REDIS_HOST = 'localhost'
SESSION_REDIS_PORT = 6379
SESSION_REDIS_DB = 2
SESSION_REDIS_PASSWORD = ''
SESSION_REDIS_PREFIX = 'session'’
实现用户注册成功就表示注册用户已经登入到美多商城系统,不用再跳转到登录页面重新登录一次。
django认证系统内部方法
状态保持,login方法的session保存到redis数据库,如果这一步卡死过不去,是因为redis数据库没有安装或配置好
Redis不支持Windows!在它官网写得很清楚。但是开发环境一般是Windows系统。为了方便开发和调试,需要在Windows中安装Redis。微软自己弄了Redis的Windows版本。
打开https://github.com/MSOpenTech/redis/releases下载msi安装包。
该版本是64位。




安装msi过程中,有个选项是否加入系统环境变量,记得勾上。一路下一步,安装。
完成之后打开cmd,输入redis-server命令查看是否可以使用,不可以则重启一下即可。
直接输入redis-server命令使用的配置文件是安装目录下的redis.windows.conf文件。 若提示错误 “ConnectionError: Error 10061 connecting to None:6379”,可打开cmd连续输入如下命令:
redis-cli shutdown
redis-server

虽然在上面的步骤中启动了redis,但是只要一关闭cmd窗口,redis服务端就会消失。所以要把redis设置成Windows下面的服务,这样,就不需要一直开着cmd窗口了。

安装服务:redis-server --service-install
卸载服务:redis-server --service-uninstall
启动服务:redis-server --service-start
停止服务:redis-server --service-stop
info #查看服务器信息
select #选择数据库索引 select 1
flushall #清空全部数据
flushdb #清空当前索引的数据库
slaveof <服务器> <端口> #设置为从服务器
slaveof no one #设置为主服务器
shutdown #关闭服务
cmd,启动redis服务器:redis-server
另开一个cmd,启动redis服务端:redis-cli
redis-cli
select 1
keys *
get :1:django.contrib.sessions.cachea3pbpgu2temlfkea1mtwf45gbj1svv5k

sesseionid: a3pbpgu2temlfkea1mtwf45gbj1svv5k,与redis服务器中session的key一致




# coding:utf-8class RETCODE:OK = "0"IMAGECODEERR = "4001"THROTTLINGERR = "4002"NECESSARYPARAMEERR = "4003"USERERR = "4004"PWDERR = "4005"CPWDERR = "4006"MOBILEERR = "4007"SMSCODERR = "4008"ALLOWERR = "4009"SESSIONERR = "4101"DBERR = "5000"EMAILERR = "5001"TELERR = "5002"NODATAERR = "5003"NEWPWDERR = "5004"OPENIDERR = "5005"PARAMERR = "5006"STOCKERR = "5007"err_msg = {RETCODE.OK : u"成功",RETCODE.IMAGECODEERR : u"图形验证码错误",RETCODE.THROTTLINGERR : u"访问过于频繁",RETCODE.NECESSARYPARAMEERR : u"缺少必传参数",RETCODE.USERERR : u"用户名错误",RETCODE.PWDERR : u"密码错误",RETCODE.CPWDERR : u"密码不一致",RETCODE.MOBILEERR : u"手机号错误",RETCODE.SMSCODERR : u"短信验证码错误",RETCODE.ALLOWERR : u"未勾选协议",RETCODE.SESSIONERR : u"用户未登录",RETCODE.DBERR : u"数据错误",RETCODE.EMAILERR : u"邮箱错误",RETCODE.TELERR : u"固定电话错误",RETCODE.NODATAERR : u"无数据",RETCODE.NEWPWDERR : u"新密码数据",RETCODE.OPENIDERR : u"无效的openid",RETCODE.PARAMERR : u"参数错误",RETCODE.STOCKERR : u"stock错误",
}
from django.urls import path, re_path
from . import viewsapp_name = 'users'urlpatterns = [# 用户注册: reverse(users:register) == '/register/'path('register/', views.ResgisterView.as_view(), name='register'), # 判断用户名是否重复注册,re_path路由正则校验,响应json数据,不需要重定向,也就不需要命名空间re_path(r'^usernames/(?P[a-zA-Z0-9-_]{5,20})/count/$', views.UsernameCountView.as_view()), ]
from meiduo_mall.utils.response_code import RETCODEclass UsernameCountView(View):""" 判断用户名是否重复注册 """def get(self, request, username):""" 参数:username(从路由中通过正则提取),响应数据:json """# 接收和校验参数:路由利用正则校验,已经实现# 主体业务逻辑:使用username查询数据库对应的记录条数count = User.objects.filter(username=username).count() # filter返回结果集,.count取出条数# 相应结果return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'count': count})



// 如果用户名符合上面的条件,然后判断用户名是否重复注册
if (this.error_name == false) { //用户名满足条件let url = '/usernames/'+ this.username +'/count/';axios.get(url, {responseType: 'json'}).then(response => {if (response.data.count ==1) { //用户名已存在this.error_name_message = '用户名已存在';this.error_name = true;} else { //用户名不存在this.error_name = false;}}).catch(error => {console.log(error.response);})
}

