Django Book 2.0 笔记——会话、用户和注册

Cookies

从 request 读取 cookies:

  
request.COOKIES[ " favorite_color " ]

 

向 response 写入 cookies:

  
response.set_cookie( " favorite_color " ,request.GET[ " favorite_color " ])

这里是基于 GET 参数来设置 cookiehtml

 

response.set_cookie() 的额外参数:

max_age None 有效期(秒),None 表示持续到浏览器关闭
expires None 失效的准确日期/时间,给出会覆盖 max_age
path / cookie 生效的路径前缀
domain None cookie 生效的域,可用于跨域
secure False 是否须要使用 HTTPS 传递本 cookie

 

Session 框架

session 框架本质上还是基于 cookies 的,只不过他再也不使用 cookies 传送文本数据,而是其哈希值。真实的数据存储在数据库中,并不发送给客户端。git

 

打开 Session 功能:

  • MIDDLEWARE_CLASSES :  'django.contrib.sessions.middleware.SessionMiddleware'
  • INSTALLED_APPS : 'django.contrib.sessions'(首次使用记得 manage.py syncdb)

 

在视图中使用 Session:

在 session 激活后,request 中就会有一个 session 对象,这也是一个类字典类型。另外注意,这个字典的 key 应当老是简单格式的字符串,不要以“_”开头,也不要访问 session 的属性,除非你知道本身在干什么。数据库

  
# Set a session value: request.session[ " fav_color " ] = " blue " # Get a session value -- this could be called in a different view, # or many requests later (or both): fav_color = request.session[ " fav_color " ] # Clear an item from the session: del request.session[ " fav_color " ] # Check if the session has a given key: if " fav_color " in request.session: ...

 

设置测试 cookie:

如下方法用于测试客户端 cookie 是否工做正常:django

  
# 在前面的视图中调用 request.session.set_test_cookie() # 在后面的视图中检查 request.session.test_cookie_worked() # 若是工做正常,则清楚测试数据 request.session.delete_test_cookie()

 

在视图外使用 Session:

由于 session 是以标准 model 的形式定义的,因此在视图外部也能够直接经过 django.contrib.sessions.models.Session 来访问。Session 的主键是一个 32 字节的字符串,这也是实际存储在 cookies 中的数据。跨域

  
>>> from django.contrib.sessions.models import Session >>> s = Session.objects.get(pk = ' 2b1189a188b44ad18c35e113ac6ceead ' ) >>> s.expire_date datetime.datetime( 2005 , 8 , 20 , 13 , 35 , 12 )

对 session 实际数据的访问须要调用对象的 get_decoded() 方法浏览器

  
>>> s.session_data ' KGRwMQpTJ19hdXRoX3VzZXJfaWQnCnAyCkkxCnMuMTExY2ZjODI2Yj... ' >>> s.get_decoded() { ' user_id ' : 42 }

一些 Session 设置:

SESSION_SAVE_EVERY_REQUEST False 是否每次收到请求都要更新 session
SESSION_EXPIRE_AT_BROWSER_CLOSE False 是否将 session 有效期设置为到浏览器关闭为止
SESSION_COOKIE_AGE 1209600 当上例为 False 时,此项生效,单位为秒
SESSION_COOKIE_DOMAIN None 用于跨域 cookie,字符串格式
SESSION_COOKIE_NAME "sessionid" cookie 的名字
SESSION_COOKIE_SECURE False 是否须要使用 HTTPS 协议

 

用户、认证与受权

Django 用户认证系统处理:用户、组、权限以及基于 cookie 的用户会话。这个系统通常被称为“auth/auth”(authentication/authorization)系统。这个名称也代表了基本的两步处理:验证用户身份,而后确认其拥有相应的权限。cookie

基于此,auth/auth 系统包含如下部分:session

  • 用户:在网站注册的人
  • 权限:标识用户是否能够进行某种操做的二进制标识:yes/no
  • 组:一种批量分配权限的方法
  • Messages:向用户显示队列式系统消息的方法

 

打开认证支持:

  • 确保 Session 已打开
  • INSTALLED_APP:'django.contrib.auth'
  • 在 SessionMiddleware 的 MIDDLEWARE_CLASSES 中添加:'django.contrib.auth.middleware.AuthenticationMiddleware'

在视图中访问用户数据,主要经过 request.user,这个对象(auth.models.User)表示当前已登陆的用户,若是对象还未登录,这就是个 AnonymousUser 对象(auth.models.AnonymousUser)。框架

判断用户是否已登陆:dom

  
request.user.is_authenticated()

 

使用 User 对象:(django 1.6 版)

auth.models.User 的属性(字段):

username 必须 30字符之内,容许使用字母数字 , _ , @ , +- 和 .(点)
first_name 可选 30字符内
last_name 可选 30字符内
email 可选 邮件地址
password 必须 任意字符、任意长度、不存明文
groups   多对多关系——Group
user_permissions   多对多关系——Permission
is_staff 布尔值 是否能够访问 admin 页面
is_active 布尔值 是否有效,须要时将其设置为 False 而不是删除帐户
is_superuser 布尔值 是否拥有全部权限
last_login datetime 默认自动更新
date_joined datetime 建立时间

auth.models.User 的方法:

get_username() 返回用户名
is_anonymous() 老是返回 False
is_authenticated() 老是返回 True
get_full_name() 返回 first_name+last_name,中间一个空格
get_short_name() 返回 first_name
set_password(raw_psw) 设定密码,若 None 则设为 unusable,不保存 User
check_password(raw_psw) 验证密码
set_unusable_password() 将用户标记为没有密码,不保存 User
has_usable_password() 若是上面方法被调用,则此方法返回 False
get_group_permissions(obj=None) 返回用户经过组获取的权限字符串的集合
get_all_permissions(obj=None) 返回用户拥有的全部权限字符串的集合
has_perm(perm,obj=None) 是否拥有某种权限
has_perms(perm_list,obj=None) 是否拥有 perm_list 中的所有权限
has_module_perms(package_name) 是否拥有某个包的所有权限
email_user(subject,message,from_email=None) 给用户发一封邮件,若是 from_email 没有给出,就使用 DEFAULT_FROM_EMAIL

auth.models.AnonymousUser

本对象模拟了 User 的接口,不过有一些不一样:

  • id 永远是 None
  • is_staff 和 is_superuser 老是 False
  • is_active 老是 False
  • groups 和 user_permissions 老是空的
  • is_anonymous() 老是返回 True
  • is_authenticated() 老是返回 False
  • set_password() , check_password() , save() , delete() 会引起 NotImplementedError 异常

 

登录和退出:

手动实现登录可使用两个函数:authenticate() 和 login()

authenticate(username, password) 负责验证给出的用户名和密码,若是验证经过,就返回一个 User 对象

login(request,user) 则直接接受一个 request 和 user 对象做为参数,并将 user 保存到 request 的 session 中

一个极简单的例子:

  
from django.contrib import auth def login_view(request): user = auth.authenticate(username = username, password = password) if user is not None and user.is_active: auth.login(request, user) return HttpResponseRedirect( " /account/loggedin/ " )

注销一个用户,调用 django.contrib.auth.logout(),他接受一个 request 做为参数,没有返回值。而且即便 request 没有登陆,本函数也不会抛出异常。

实际中,并不须要上面这样手动实现验证和登陆。使用内建的 login、logout 视图函数:

  
from django.contrib.auth.views import login, logout urlpatterns = patterns( '' , (r ' ^accounts/login/$ ' , login), (r ' ^accounts/logout/$ ' , logout), )

/accounts/login//accounts/logout/ 是Django提供的视图的默认URL,能够在 settings 中修改。

缺省情况下,login 视图渲染 registragiton/login.html 模板(或者能够经过 template_name 参数指定其余模板)

logout视图有一些不一样。 默认状况下它渲染 registration/logged_out.html 模板(这个视图通常包含你已经成功退出的信息)。 视图中还能够包含一个参数 next_page 用于退出后重定向。

 

对于某些须要登陆才能访问的视图,可使用 login_required 装饰器:

  
from django.contrib.auth.decorators import login_required @login_required def my_view(request): # ...

这个装饰器会在用户未登陆时将页面重定向至 /accounts/login/,并将当前页面 url 当作 next 在查询字符串中传递过去,例如:/accounts/login/?next=/polls/3/ ,这样有助于用户登录后自动跳转回当前页面。

 

还有一些状况,不仅须要登陆,还须要验证相应的权限。这里一样有一个装饰器可用:

  
def user_can_vote(user): return user.is_authenticated() and user.has_perm( " polls.can_vote " ) @user_passes_test(user_can_vote, login_url = " /login/ " ) def vote(request): # Code here can assume a logged-in user with the correct permission. ...

user_passes_test 使用一个必需的参数: 一个可调用的方法,当存在 User 对象并当此用户容许查看该页面时返回True 。 注意 user_passes_test 不会自动检查 User

 

管理 Users、Permissions 和 Groups

Users

由于 User 就是一个标准模型,因此使用通常性的模型操做应该就能完成任务,不过 User 仍是提供了一个辅助函数 create_user() 用以建立 User 实例而不是直接调用 User 来实例化它:

  
>>> from django.contrib.auth.models import User >>> user = User.objects.create_user(username = ' john ' , ... email = ' jlennon@beatles.com ' , ... password = ' glass onion ' )

对 User 对象的 password 的修改,应经过 set_password() 方法来实现,由于这个属性存储的并非明文。

  
>>> user = User.objects.get(username = ' john ' ) >>> user.set_password( ' goo goo goo joob ' ) >>> user.save()

处理注册:

在注册的问题上,比较有用的是 django 提供了一个内建的 Form :

  
from django import forms from django.contrib.auth.forms import UserCreationForm from django.http import HttpResponseRedirect def register(request): if request.method == ' POST ' : form = UserCreationForm(request.POST) if form.is_valid(): new_user = form.save() return HttpResponseRedirect( " /books/ " )

Permissions & Groups

略...

相关文章
相关标签/搜索