本站首页    管理页面    写新日志    退出


«December 2025»
123456
78910111213
14151617181920
21222324252627
28293031


公告
 本博客在此声明所有文章均为转摘,只做资料收集使用。

我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:
日志总数:1304
评论数量:2242
留言数量:5
访问次数:7667041
建立时间:2006年5月29日




[Django]如何使用 session
软件技术

lhwork 发表于 2007/2/3 13:44:46

Django 完全支持匿名 session. session 框架允许每一个用户保存并取回数据. 它抽象发送及接收 cookies 并在服务器端保存数据. Cookie 中包含一个 session ID -- 并不是数据本身. 启用 sessions 默认情况下, Session 功能就是启用的. 通过修改 MIDDLEWARE_CLASSES 设置你可以手工启用或关闭 session 功能.要激活 session 功能, 你要保证 MIDDLEWARE_CLASSES 包含 "django.contrib.sessions.middleware.SessionMiddleware". 如果你不想使用 sessions, 在 MIDDLEWARE_CLASSES 中移除 SessionMiddleware 行. 这会为你的系统减少一点负载. 在 views 中使用 session 每一个 HttpRequest 对象 -- 即任意 Django view 函数的第一个参数 -- 拥有一个 session 属性, 该属性是一个行为类似字典的可读写对象. 它实现了以下标准字典方法: __contains__(key) 例子: 'fav_color' in request.session__getitem__(key) 例子: fav_color = request.session['fav_color']__setitem__(key, value) 例子: request.session['fav_color'] = 'blue'__delitem__(key) 例子: del request.session['fav_color']. This raises KeyError if the given key isn't already in the session.get(key, default=None) 例子: fav_color = request.session.get('fav_color', 'red')keys()items() 它还拥有以下三个方法: set_test_cookie() 设置一个测试 cookie 以判断用户浏览器是否支持 cookie. 由于 cookie 的工作方式, 除非得到用户的下一请求页面,你无法知道用户浏览器是否支持cookie. 阅读阅读下文中的 "Setting test cookies" 可以得到更多信息.test_cookie_worked() 根据用户浏览器是否接受测试cookie 返回 True 或 False, 由于cookie 特殊的工作方式, 你必须在前一个独立的页面请求中调用 set_test_cookie() .阅读下文中的 "Setting test cookies" 可以得到更多信息.delete_test_cookie() 删除测试 cookie. 可以用它来清理你的 cookie. 在你的 view 的任何部分都可以编辑 request.session , 你也可以在 view 中多次修改它的值. Session 对象指南 使用常规的 Python 字符串作为字典的 request.session 的 key. 这是一个使用惯例而不是硬性规定.下划线开头的 Session key 被保留为由 Django 内部使用.不要用一个新对象覆盖 request.session , 也不要访问或设置它的属性. 你应该一直把它当成一个字典来使用. 几个例子 下面这个极为简单的 view 在用户发表了一个评论之后将 has_commented 变量的值设置为 True . 它只允许用户发表一次评论: def post_comment(request, new_comment): if request.session.get('has_commented', False): return HttpResponse("You've already commented.") c = comments.Comment(comment=new_comment) c.save() request.session['has_commented'] = True return HttpResponse('Thanks for your comment!') 下面这个 view 则用于一个站点的用户登录: def login(request): m = members.get_object(username__exact=request.POST['username']) if m.password == request.POST['password']: request.session['member_id'] = m.id return HttpResponse("You're logged in.") else: return HttpResponse("Your username and password didn't match.") ...这一个则根据上面的 login() 用于用户登出: def logout(request): try: del request.session['member_id'] except KeyError: pass return HttpResponse("You're logged out.") 设置测试 cookie 方便起见, Django 提供了一个简单有效的方式来测试用户浏览器是否接受 cookie .在一个 view 中调用 request.session.set_test_cookie() 然后在后面的view中调用 request.session.test_cookie_worked() -- 注意不能是同一个 view 的两次调用. 这种看似笨拙将 set_test_cookie() 及 test_cookie_worked() 分成两步执行的方法是不得以的. 当你设置一个 cookie 以后,在浏览器的下一次请求之前,你无法知道浏览器是否接受了它. 在测试完毕之后, 及时使用 delete_test_cookie() 清理掉测试 cookie 是一个好习惯. 下面是一个典型应用的例子: def login(request): if request.POST: if request.session.test_cookie_worked(): request.session.delete_test_cookie() return HttpResponse("You're logged in.") else: return HttpResponse("Please enable cookies and try again.") request.session.set_test_cookie() return render_to_response('foo/login_form.html') 在 view 之外使用 session 在系统内部, 每一个 session 都是一个 Django model. Session model 定义在 django/contrib/sessions/models.py. 因为它就是一个普通的 model ,你可以使用常规的 Django 数据库 API 访问 sessions.: >>> from django.contrib.sessions.models import Session>>> s = Session.objects.get_object(pk='2b1189a188b44ad18c35e113ac6ceead')>>> s.expire_datedatetime.datetime(2005, 8, 20, 13, 35, 12) 注意你需要调用 get_decoded() 来得到 session 字典. 这一步是必须的, 因为这个字典是被编码以后存储的: >>> s.session_data'KGRwMQpTJ19hdXRoX3VzZXJfaWQnCnAyCkkxCnMuMTExY2ZjODI2Yj...'>>> s.get_decoded(){'user_id': 42} 何时保存 session 默认情况下, Django 只在 session 被修改时保存 session 到数据库 -- 也就是 session 被赋值或删除时: # Session被修改request.session['foo'] = 'bar'# Session被修改del request.session['foo']# Session被修改request.session['foo'] = {}# Gotcha: Session 未被修改, 因为它改变的是# request.session['foo'] 而不是 request.session.request.session['foo']['bar'] = 'baz' 要改变这种默认行为, 将 SESSION_SAVE_EVERY_REQUEST 设置为 True. 若 SESSION_SAVE_EVERY_REQUEST 为 True, Django 会在发生任何一次单独的请求时保存 session 到数据库. 注意 session cookie 仅当一个 session 变量被创建或修改时才将其发送到客户端.如果 SESSION_SAVE_EVERY_REQUEST 为 True, session cookie 就会在任何一次请求时被发送. 类似的, 一个 session cookie 的 expires 部分在发送 session cookie 时也将自动更新. 设置 几个 Django settings 允许你控制 session 的行为: SESSION_COOKIE_AGE 默认值: 1209600 (2 周, 以秒计) session cookie 的有效期, 以秒计. SESSION_COOKIE_DOMAIN 默认值: None 使用 session cookie 的域. 如果要 session cookie 跨域工作, 将它设置为类似 ".lawrence.com" , 否则就设置为 None (标准cookie工作方式). SESSION_COOKIE_NAME 默认值: 'sessionid' session cookie 的名字. 你可以任意设置. SESSION_SAVE_EVERY_REQUEST 默认值: False 是否每次请求都保存 session 数据. 若值为 False (默认), 则仅当 session 内容改变时才保存 -- 也就是, 当任何字典值被赋值或删除时. 技术细节 session 字典接受任何 pickleable Python 对象. 参阅 the pickle module 了解更多信息.Session 数据被保存在数据库中的 django_session 表中.Django 仅在需要时才发送 cookie . 如果你没有设置任何 session 数据, 它就不会发送任何 cookie. URL 中的 Session ID Django sessions 框架基于 cookie, 它完整并且独立. 它不会将 session id 放到 url 中作为最后的手段(PHP是那样). 我们故意让它这样(不使用url), 不仅仅是因为那种行为使得 url 很丑陋, 主要是因为那样会使得你的站点易被攻击.(通过 "Referer"头窃取 session-ID).


阅读全文(4000) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 2.988 second(s), page refreshed 144812537 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号