Djangosession详解
Django中的session是⼀个⾼级⼯具,它可以让⽤户存储个⼈信息以便在下次访问⽹站中使⽤这些信息。session的基础还是cookie,但是它提供了⼀些更加⾼级的功能。请看下⾯的⼀个例⼦:
使⽤session:
这个例⼦中实现了⼀个简单的计数功能:
def test_count_session(request):
if 'count' in request.session:
request.session['count'] += 1
return HttpResponse('new count=%s' % request.session['count'])
else:
request.session['count'] = 1
return HttpResponse('No count in session. Setting to 1')
⽐较session和cookie的使⽤我们可以发现他们有⼀下⼏点不同:
session管理更加统⼀和⽅便:每个session中的属性值可以使⽤查询以及修改操作。
虽然我们在例⼦中只是使⽤了⼀个整数的属性,但实际上session中还可以包含很多类型的属性,⽐如字典属性,并且它可以很⽅便地⽤中的内建⽅法访问它们。
虽然我们在session中设置了⼀个计数器count,但是如果我们抓取当前的cookie时会发现,竟然没有count这个属性!⽽只是设置了⼀个看起来似乎是唯⼀标识的sesionid,这当然是处于安全⽅⾯的考虑。假定⽤户不停地访问⼀个页⾯,⽐如访问了10次,那我们是不是就要对他的计数器+10次呢?显然这样做不符合实际情况,有了这个sessionid,我们就可以判断是否是同⼀个⽤户访问⼀个页⾯了。
Set-Cookie:sessionid=a92d67e44a9b92d7dafca67e507985c0;
expires=Thu, 07-Jul-2011 04:16:28 GMT;
Max-Age=1209600;
Path=/
深⼊了解sessionid:
默认情况下,Django会将session保存在django_session这个表中:
CREATE TABLE "django_session" (
"session_key" varchar(40) NOT NULL PRIMARY KEY,
"session_data" text NOT NULL,
"expire_date" datetime NOT NULL
);
其中的session_key就相当于cookie中保存的sessionid,⽽session_data就包含了当前session中的属性。
如果想详细看看我们上⾯创建的session的信息,可以像下⾯这样:
dels import Session
#...
sess = (pk='a92d67e44a9b92d7dafca67e507985c0')
print(sess.session_data)
_decoded())
它或许会输出类似下⾯的信息:
ZmEyNDVhNTBhMTk2ZmRjNzVlYzQ4NTFjZDk2Y2UwODc3YmVjNWV
jZjqAAn1xAVUFY291bnRxAksGcy4=
{'count': 11}
Django会保存request.session的相关信息到数据库,然后⽤户可以通过cookie中的sessionid对它进⾏各种操作。当然这些操作我们可以通过Django⾃带的session模块轻松操作,从⽽简化了程序员的⼯作。下⾯我们来详细了解⼀下Django中的session。
session中间件:
⾸先看看Django中的django.http.HttpRequest,了解⼀下它是如何取得session并对其属性进⾏操作的。
中对它有详细的介绍,我们这⾥就简单的说⼀下原理吧 !
django项目实例视图⽅法接受⼀个httprequest后,对它进⾏⼀系列的操作,然后返回⼀个httpresponse。⽽中间件增加⼀些额外的操作:
Django的中间件框架就是⼀些所谓的hook类,它设置在Django项⽬中的settings中的MIDDLEWARE_CLASSES内。当然您也可以添加⾃⼰的MIDDLEWARE_CLASSES。
默认情况下,ib.sessions.middleware.SessionMiddleware 是⾃动添加的。查看它的源代码,我们可以发现它实际上就是实现了2个hooks:process_request和process_response。
process_request提取当前cookie中的session KEY(也就是sessionid),其中SESSION_COOKIE_NAME就是我们说的sessionid。⽽request.session则包含了"session store"对象。
process_response负责保存"session store"对象并将它返回给客户端。
session的存储:
Django中可以通过设置SESSION_ENGINE属性来指定后台引擎来处理session。默认是ib.sessions.backends.db。
在Django安装⽬录中的sessions/backends下可以到很多其他的引擎,这⾥就不再赘述。
不管是哪⼀种引擎,它都实现了⼀个StorageSession类,其中包含了对session的各种操作⽅法。
为了理解它的⼯作原理,假定⽤户想访问request.session,来看看它的⼯作流程:
1. Session中间件的process_request实例化⼀个request.session,并将db.SessionStore附带session_key保存到构造函数(姑且
这么叫吧,实在想不到好听的名字)。
2. SessionStore的构造函数会保存session key以便⽤户访问。
3. process_request的⼯作就算完成了,接着session中间件会将request传给view⽅法。
4. SessionBase是⼀个类字典实例,我们可以通过Python内建的字典⽅法对它进⾏操作,例如__getitem__。它还有⼀个很有⽤的⽅
法:_get_session(它⽤到了load⽅法,load⽅法是由db.SessionStore来执⾏的,⽽不是SessionBase,期间还有⼀些对数据的编码⼯作)
下⾯来看⼀个简单的例⼦:
def encode(self, session_dict):
"Returns the given session dictionary pickled and encoded as a string."
pickled = pickle.dumps(session_dict, pickle.HIGHEST_PROTOCOL)
hash = self._hash(pickled)
destring(hash + ":" + pickled)
结论:
Django基于最简单的HTTP request和HTTP response⽽实现session的使⽤。希望上⾯的⼀些东西能给您带来⼀些灵感,如果需要详细了解session,读者可以当django官⽹的session⽂档中去。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论