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

略...

相關文章
相關標籤/搜索