柴少的博客 也许终将一事无成,却不能甘于平庸。

Django之session操作(十)

一、Session介绍

1.1 session机制

      session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
      当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识 - 称为session id,如果已包含一个session id则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(如果检索不到,可能会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。

      在谈论session机制的时候,常常听到这样一种误解“只要关闭浏览器,session就消失了”。其实可以想象一下会员卡的例子,除非顾客主动对店家提出销卡,否则店家绝对不会轻易删除顾客的资料。对session来说也是一样的,除非程序通知服务器删除一个session,否则服务器会一直保留,程序一般都是在用户做log off的时候发个指令去删除session。然而浏览器从来不会主动在关闭之前通知服务器它将要关闭,因此服务器根本不会有机会知道浏览器已经关闭,之所以会有这种错觉,是大部分session机制都使用会话cookie来保存session id,而关闭浏览器后这个session id就消失了,再次连接服务器时也就无法找到原来的session。如果服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求头,把原来的session id发送给服务器,则再次打开浏览器仍然能够找到原来的session。
      恰恰是由于关闭浏览器不会导致session被删除,迫使服务器为seesion设置了一个失效时间,当距离客户端上一次使用session的时间超过这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把session删除以节省存储空间。

      session服务端中存在的数据为:

session = {
   随机字符串1:{
   用户1的相关信息
}
   随机字符串2:{
   用户2的相关信息
}
}
#session客户端即客户端的浏览器的cookie中存的数据是当前用户对应的随机字符串

http://justsee.iteye.com/blog/1570652  #介绍的很详细

1.2 session的工作过程

session的工作过程为:

  1. 生成随机字符串 

  2. 写到用户浏览器的cookie中

  3. 保存到session中

  4. 在随机字符串对应的字典中设置相关内容

而在django中,request.session['username'] = user 就会把需要的四步骤都给做了。

注意的是:

如果想用session的功能呢 先要创建对应的数据库表。所以在Django中要用session中一定要先执行:
python manage.py makemigrations
python manage.py migrate

1.3 session的使用:

  def index(request):
        # 获取、设置、删除Session中数据
        request.session['k1']   #里面已经包含了 request.session.exists,所以 request.session.exists用不到。
        request.session.get('k1',None)   #和上面的区别是第一条是如果取不到就报错,第二个是取不到返回一个None。
        request.session['k1'] = 123
        request.session.setdefault('k1',123) 
        #上面两条的区别是,第一条是不存在就创建存在就更新,下面这条存在则不设置
        del request.session['k1']   #删除当前用户session里面的某一键值给删掉了       
        # 所有 键、值、键值对
        request.session.keys()
        request.session.values()
        request.session.items()
        request.session.iterkeys()
        request.session.itervalues()
        request.session.iteritems()
                #上面就是对字典进行循环
 
        #用户session的随机字符串
        request.session.session_key
 
        # 将所有Session失效日期小于当前日期的数据删除
        request.session.clear_expired()  #数据库里面旧的记录不会自动删除就是脏数据了所以这样执行一下,不过缓存里面又自动删除过期数据的机制。
 
        # 检查 用户session的随机字符串 在数据库中是否
        request.session.exists("session_key")  
 
        # 删除当前用户的所有Session数据
        request.session.delete("session_key")
        request.session.clear()   #这个点注销的时候用
 
        request.session.set_expiry(value)
            * 如果value是个整数,session会在些秒数后失效。也可以(60*60)
            * 如果value是个datatime或timedelta,session就会在这个时间后失效。
            * 如果value是0,用户关闭浏览器session就会失效。
            * 如果value是None,session会依赖全局session失效策略。
                #django的session失效时间默认是2周。如果不想走默认就是上面的设置。

1.4 django里面的默认设置,如果要修改需要配置settings.py

    SESSION_ENGINE = 'django.contrib.sessions.backends.db'   #引擎(默认)

    SESSION_COOKIE_NAME = "sessionid"   #Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
    SESSION_COOKIE_PATH = "/"     #Session的cookie保存的路径(默认)
    SESSION_COOKIE_DOMAIN = None    #Session的cookie保存的域名(默认)
    SESSION_COOKIE_SECURE = False   #是否Https传输cookie(默认)
    SESSION_COOKIE_HTTPONLY = True  #是否Session的cookie只支持http传输(默认)
    SESSION_COOKIE_AGE = 1209600   #Session的cookie失效日期(2周)(默认)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False  #是否关闭浏览器使得Session过期(默认)
    SESSION_SAVE_EVERY_REQUEST = False #是否每次请求都保存Session,默认修改之后才保存(默认)#如果这里改为True,就变成了最后一次操作的超时时间而不是登录开始计算超时时间。

1.5 Django中对于session的存储方式

Django中默认支持Session,其内部提供了5种类型的Session供开发者使用:
数据库(默认)
缓存
文件
缓存+数据库
加密cookie

缓存session

#配置 settings.py
 SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  #引擎    
 SESSION_CACHE_ALIAS = 'default'   #使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置

文件Session

SESSION_ENGINE = 'django.contrib.sessions.backends.file'    #引擎
 SESSION_FILE_PATH = None  #缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()                                                           
 # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T

缓存+数据库Session

#数据库用于做持久化,缓存用于提高效率
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'   #引擎

加密cookie Session

SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   #引擎

二、来点例子

2.1 做一个基于session做用户登录:

python manage.py makemigrations
python manage.py migrate

#先把上面两步操作做了

views.py:

from django.shortcuts import render,redirect,HttpResponse
# Create your views here.

def login(request):
    if request.method == "GET":
        return render(request,'login.html')
    elif request.method == "POST":
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        if user == 'root' and pwd == "123":
            # session中设置值
            #生成随机字符串、写到用户浏览器cookie、保存到session中、在随机字符串对应的字典中设置相关内容
            request.session['username'] = user
            #上面一句话django就会把需要的四步骤都给做了,首先表示在本地浏览器会生成随机字符串,会在服务器端生成对应的username对应的键值对。
            request.session['is_login'] = True  #表示登录成功
            return redirect('/index/')
        else:
            return render(request,'login.html')
def index(request):
    # session中获取值
    #获取当前用户的随机字符串,根据随机字符串获取对应信息
    if request.session['is_login']:
        return HttpResponse(request.session['username'])
    else:
        return HttpResponse('gun')

login.html :

<body>
   <form action="/login/" method="POST">
       <input type="text" name="user" />
       <input type="text" name="pwd" />
       <input type="submit" value="提交" />
   </form>
</body>

index.html :

<body>
   <p>欢迎登陆:{{ username }}</p>
</body

登录测试:

图片.png

#上面这个随机字符串给浏览器一个,默认在后台mysql数据库里面也有一个。

图片.png

#session_key是发给客户端的key也就相当于存在字典里,面的keysession_data就相当于对用户名进行的一个随机加密字符串,本质就是一个username = root

2.2  再来个注销的小例子

views.py:

def index(request):
    # session中获取值
    #if request.session['is_login']:
    if request.session.get('is_login',None):  #这里是防止注销后拿不到数据报错
        return render(request,'index.html',{'username':request.session['username']})  #{'username':request.session['username']}这个可传可不传,request里面已经把内容全放到前端了
    else:
        return HttpResponse('gun')
def logout(request):
    #del request.session['username']
    request.session.clear()
    return redirect('/login/')

index.html:

<body>
   <p>欢迎登陆:{{ username }},{{ request.session.username }}</p>
   <a href="/logout/">注销</a>
</body>

图片.png

作者:chaishaopeng 分类:Django学习 浏览:1803 评论:0
留言列表
发表评论
来宾的头像