好男人天堂网,久久精品国产这里是免费,国产精品成人一区二区,男人天堂网2021,男人的天堂在线观看,丁香六月综合激情

當(dāng)前位置:首頁 > 網(wǎng)站舊欄目 > 學(xué)習(xí)園地 > 設(shè)計(jì)軟件教程 > 翻譯www.djangobook.com之第十二章:會(huì)話,用戶和注冊(cè)

翻譯www.djangobook.com之第十二章:會(huì)話,用戶和注冊(cè)
2010-01-13 23:41:25  作者:  來源:
是時(shí)候承認(rèn)了:我們故意忽略了一個(gè)web開發(fā)極端重要的方面,到目前為止,我們考慮了大量未露面的匿名用戶訪問我們
站點(diǎn)頁面的流量情況,這當(dāng)然不正確,訪問我們站點(diǎn)的瀏覽器后面是真實(shí)的人(至少有些時(shí)候是這樣),這是被忽略的一個(gè)
大問題:當(dāng)Internet服務(wù)于人而不是機(jī)器時(shí)是工作的最好的,如果我們開發(fā)真正引人注目的站點(diǎn)時(shí),最終我們將不得不與
瀏覽器后面的人打交道
不幸的是,這并不容易,HTTP被設(shè)計(jì)為無狀態(tài),即每個(gè)請(qǐng)求發(fā)生在一個(gè)空間里,兩個(gè)請(qǐng)求之間沒有持久化,并且我們不能
計(jì)算一個(gè)請(qǐng)求的每個(gè)方面(IP地址,用戶代理等等)來一致的顯示同一個(gè)人的連續(xù)請(qǐng)求
瀏覽器開發(fā)人員很久之前就意識(shí)到HTTP的無狀態(tài)導(dǎo)致了web開發(fā)人員很大的麻煩,就這樣cookies誕生了
cookie是一個(gè)小信息片段,瀏覽器存儲(chǔ)它來代表web服務(wù)器,每次瀏覽器從某一服務(wù)器請(qǐng)求一個(gè)頁面時(shí)都會(huì)把它起初接受
的cookie回傳過去

Cookies
讓我們看看它可能怎樣工作,當(dāng)你開啟瀏覽器并鍵入google.com,你的瀏覽器像這樣開始來發(fā)送一個(gè)HTTP請(qǐng)求到Google:
GET / HTTP/1.1
Host: google.com
...
當(dāng)Google回復(fù)時(shí),HTTP應(yīng)答看起來像這樣:
HTTP/1.1 200 OK
Content-Type: text/html
Set-Cookie: PREF=ID=5b14f22bdaf1e81c:TM=1167000671:LM=1167000671;
            expires=Sun, 17-Jan-2038 19:14:07 GMT;
            path=/; domain=.google.com
Server: GWS/2.1
注意Set-Cookie頭部,你的瀏覽器將存儲(chǔ)這個(gè)cookie值(PREF=ID=5b14f22bdaf1e81c:TM=1167000671:LM=1167000671)并在
每次你訪問這個(gè)站點(diǎn)時(shí)回傳給Google,所以下一次你訪問Google時(shí)你的瀏覽器將傳遞像這樣的請(qǐng)求:
GET / HTTP/1.1
Host: google.com
Cookie: PREF=ID=5b14f22bdaf1e81c:TM=1167000671:LM=1167000671
...
然后Google可以使用這個(gè)Cookie值來知道你是早些時(shí)候訪問這個(gè)站點(diǎn)的同一個(gè)人
例如,這個(gè)值可能是數(shù)據(jù)庫存儲(chǔ)用戶信息的鍵,Google可以(也確實(shí))使用它來在頁面上顯示你的名字

得到和設(shè)置cookies
當(dāng)在Django中處理持久化時(shí),大部分時(shí)候你想使用稍后討論的高級(jí)session和/或用戶框架,盡管如此,我們將停下來先
看看在Django中怎樣讀和寫cookies,它將幫助你理解本章其它部分事實(shí)上怎樣工作,并且如果你需要直接操作cookies
的話它將觸手可得
讀取已經(jīng)設(shè)置的cookies是非常簡單的:每個(gè)request對(duì)象都有一個(gè)類似字典的COOKIES對(duì)象,你可以使用它來讀瀏覽器發(fā)送
到視圖的任何cookies:
Java代碼 復(fù)制代碼
  1. def show_color(request):   
  2.     if "favorite_color" in request.COOKIES:   
  3.         return HttpResponse("Your favorite color is %s" % \   
  4.             request.COOKIES["favorite_color"])   
  5.     else:   
  6.         return HttpResponse("You don't have a favorite color.")  

寫cookies更復(fù)雜一點(diǎn),你需要使用HttpResponse對(duì)象的set_cookie()方法,這里是一個(gè)基于GET參數(shù)設(shè)置favorite_color
cookie的例子:
Java代碼 復(fù)制代碼
  1. def set_color(request):   
  2.     if "favorite_color" in request.GET:   
  3.   
  4.         # Create an HttpResponse object...   
  5.         response = HttpResponse("Your favorite color is now %s" % \   
  6.             request.GET["favorite_color"])   
  7.   
  8.         # ... and set a cookie on the response   
  9.         response.set_cookie("favorite_color",   
  10.                             request.GET["favorite_color"])   
  11.   
  12.     else:   
  13.         return HttpResponse("You didn't give a favorite color.")  

你也可以傳遞一些可選參數(shù)到request.set_cookie()來控制cookie的一些方面:
Parameter        Default        Description
max_age          None           cookie持續(xù)的時(shí)間(秒),如果為None,cookie將只持續(xù)到瀏覽器關(guān)閉
expires          None           cookie過期的準(zhǔn)確日期/時(shí)間,格式應(yīng)為"Wdy, DD-Mth-YY HH:MM:SS GMT"
                                如果給定值,它將覆蓋max_age參數(shù)
path             "/"            cookie的合法的路徑前綴,瀏覽器將只把cookie傳遞回該路徑前綴下,所以你可以
                                使用它來防止cookies被傳遞給你的站點(diǎn)的其它部分,當(dāng)你不控制你的站點(diǎn)域名的
                                頂級(jí)部分時(shí)這非常有用
domain           None           cookie的合法域名,你可以使用它來設(shè)置跨域名的cookie,例如,domain=".examp
                                le.com"將設(shè)置一個(gè)可以被www.example.com,www2.example.com和an.other.sub.
                                domain.example.com讀取的cookie
                                如果設(shè)置為None,cookie將只能被設(shè)置它的域名讀取
secure           False          如果設(shè)置為True,它將指示瀏覽器只當(dāng)通過HTTPS訪問頁面時(shí)返回這個(gè)cookie

cookies的混合祝福
你可能注意到cookies工作的一些潛在的問題,讓我們看看一些重要的:
1,Cookies本質(zhì)上是自發(fā)的,瀏覽器不保證cookies的存儲(chǔ),事實(shí)上,這個(gè)行星上的每個(gè)瀏覽器都讓你控制你的瀏覽器的
接受cookies的策略,如果你想看重要的cookies怎樣到達(dá)web,嘗試打開瀏覽器的"接受每個(gè)cookie"選項(xiàng),甚至一個(gè)巨大
的藍(lán)色怪物都將填充所有這些cookies!
當(dāng)然,這意味著cookies上不可信任的定義,開發(fā)人員應(yīng)該檢查用戶在信賴它們之前接受了cookies
更重要的是,你應(yīng)該從不在cookies里面存儲(chǔ)重要數(shù)據(jù),web充滿了開發(fā)人員為了某些原因在瀏覽器cookies里存儲(chǔ)不可重
獲的信息來使瀏覽器方便的恐怖故事
2,Cookies不是安全的,因?yàn)镠TTP數(shù)據(jù)傳輸?shù)氖敲魑,cookies非常容易受竊聽攻擊,即攻擊者在線上竊聽可以截取
cookie并讀取它,這意味著你應(yīng)該從不在cookie里存儲(chǔ)敏感信息
還有更陰險(xiǎn)的"中間人"攻擊,其中一個(gè)攻擊者截取cookie并使用它來假裝為另一個(gè)用戶,第20章深入討論了這種攻擊現(xiàn)象
并給出了預(yù)防的辦法
3,Cookies甚至對(duì)預(yù)定的接受者都不安全,大多數(shù)瀏覽器提供簡易方式來編輯單獨(dú)cookies的內(nèi)容,并且足智多謀的用戶
可以使用像mechanize的工具來手動(dòng)構(gòu)建HTTP請(qǐng)求
所以你不能在cookies里存儲(chǔ)可竄改的敏感數(shù)據(jù),這種情形下的標(biāo)準(zhǔn)錯(cuò)誤是當(dāng)用戶登錄后在cookie里存儲(chǔ)像IsLoggedIn=1
的東西,你會(huì)對(duì)大量的站點(diǎn)犯這種錯(cuò)誤而感到驚奇,只需花一秒鐘就可以愚弄這些站點(diǎn)的"安全"系統(tǒng)

Django的session框架
由于這些限制和潛在的安全漏洞,很顯然cookies和持久化sessions是另一個(gè)web開發(fā)里頭疼的地方,當(dāng)然Django的目標(biāo)是
做高效的頭疼殺手,所以Django帶來一個(gè)為你掃平這些困難的session框架
這個(gè)session框架讓你基于一個(gè)站點(diǎn)訪問者存儲(chǔ)和得到任意數(shù)據(jù),它在服務(wù)器端存儲(chǔ)數(shù)據(jù)并抽象發(fā)送和接受cookies
Cookies只使用一個(gè)哈希session ID而不是數(shù)據(jù)本身,這樣可以防止大部分通常的cookie問題

允許sessions
Sessions通過一個(gè)中間件(參考第16章)和一個(gè)Django模型實(shí)現(xiàn),你需要做如下事情來允許sessions:
1,編輯你的MIDDLEWARE_CLASSES設(shè)置并確認(rèn)MIDDLEWARE_CLASSES包含'django.contrib.sessions.middleware.Session
Middleware'
2,確認(rèn)'django.contrib.sessions'在你的INSTALLED_APPS設(shè)置里(如果你需要添加它還要允許manage.py syncdb)
通過startproject創(chuàng)建的默認(rèn)骨架設(shè)置已經(jīng)安裝了這兩項(xiàng),所以除非你已經(jīng)刪除了它們,你很可能不需要改變?nèi)魏螙|西
就可以讓sessions工作
如果你不想使用sessions,你可能想從MIDDLEWARE_CLASSES刪除SessionMiddleware行和從INSTALLED_APPS刪除
'django.contrib.sessions',它將只保存一個(gè)很小的過度,但是這很小的部分起作用

在視圖里使用sessions
當(dāng)SessionMiddleware激活后,每個(gè)HttpRequest對(duì)象--每個(gè)Django視圖方法的第一個(gè)參數(shù)--將有一個(gè)session屬性,它是
一個(gè)類似字典的對(duì)象,你可以像使用普通的字典一樣讀寫它,例如,你可以在視圖中做這樣的事情:
Java代碼 復(fù)制代碼
  1. # Set a session value:   
  2. request.session["fav_color"] = "blue"  
  3.   
  4. # Get a session value -- this could be called in a different view,   
  5. # or many requests later (or both):   
  6. fav_color = request.session["fav_color"]   
  7.   
  8. # Clear an item from the session:   
  9. del request.session["fav_color"]   
  10.   
  11. # Check if the session has a given key:   
  12. if "fav_color" in request.session:   
  13.     ...  

你也可以在request.session使用像keys()和items()的其它映射方法
有一些高效使用Django的sessions的簡單規(guī)則:
1,在request.session使用普通的Python字符串作為字典的鍵(而不是integers,objects等等),這是一個(gè)慣例,但是值
得遵循
2,以下劃線開始的session字典鍵被Django保留作內(nèi)部使用,實(shí)踐中框架只使用非常少的下劃線前綴的session變量,但
是除非你知道它們都是些什么(并且想跟上Django本身的更改),最好遠(yuǎn)離它們以防Django妨礙你的app
3,不要用新的對(duì)象覆蓋request.session,并且不要訪問或者設(shè)置它的屬性,像Python字典一樣使用它
讓我們看看一些快速的例子,簡單的視圖在用戶提交一個(gè)comment后設(shè)置一個(gè)has_commented變量為True,它不讓一個(gè)用戶
提交一個(gè)comment多于一次:
Java代碼 復(fù)制代碼
  1. def post_comment(request, new_comment):   
  2.     if request.session.get('has_commented', False):   
  3.         return HttpResponse("You've already commented.")   
  4.     c = comments.Comment(comment=new_comment)   
  5.     c.save()   
  6.     request.session['has_commented'] = True   
  7.     return HttpResponse('Thanks for your comment!')  

簡單的視圖在站點(diǎn)登錄一個(gè)"成員":
Java代碼 復(fù)制代碼
  1. def login(request):   
  2.     m = members.get_object(username__exact=request.POST['username'])   
  3.     if m.password == request.POST['password']:   
  4.         request.session['member_id'] = m.id   
  5.         return HttpResponse("You're logged in.")   
  6.     else:   
  7.         return HttpResponse("Your username and password didn't match.")  

這個(gè)例子根據(jù)上面的login()注銷一個(gè)成員:
Java代碼 復(fù)制代碼
  1. def logout(request):   
  2.     try:   
  3.         del request.session['member_id']   
  4.     except KeyError:   
  5.         pass   
  6.     return HttpResponse("You're logged out.")  

注意,實(shí)踐中這是登錄用戶的惡心的方式,下面討論的認(rèn)證框架以更健壯和有用的方式為你處理這些,這些內(nèi)容只是提供
容易理解的例子

設(shè)置測試cookies
上面提到,你不能依賴每個(gè)瀏覽器接受cookies,所以,為了方便起見,Django提供了一個(gè)簡單的方式來測試用戶的瀏覽器
是否接受cookies,你只需在視圖中調(diào)用request.session.set_test_cookie()并在后面的視圖中檢查requet.session.test
_cookie_worked(),而不是在同一個(gè)視圖中調(diào)用
由于cookies的工作方式,這樣笨拙的分離set_test_cookie()和test_cookie_worked()很必要,當(dāng)你設(shè)置一個(gè)cookie,你
事實(shí)上不能分辨瀏覽器是否接受它,直到瀏覽器下一次請(qǐng)求
你自己使用delete_test_cookie()來清除測試cookie是良好的實(shí)踐,在你驗(yàn)證測試cookie工作后做這件事
這里是一個(gè)典型的使用例子:
Java代碼 復(fù)制代碼
  1. def login(request):   
  2.   
  3.     # If we submitted the form...   
  4.     if request.method == 'POST':   
  5.   
  6.         # Check that the test cookie worked (we set it below):   
  7.         if request.session.test_cookie_worked():   
  8.   
  9.             # The test cookie worked, so delete it.   
  10.             request.session.delete_test_cookie()   
  11.   
  12.             # In practice, we'd need some logic to check username/password   
  13.             # here, but since this is an example...   
  14.             return HttpResponse("You're logged in.")   
  15.   
  16.         # The test cookie failed, so display an error message. If this  
  17.         # was a real site we'd want to display a more friendly message.   
  18.         else:   
  19.             return HttpResponse("Please enable cookies and try again.")   
  20.   
  21.     # If we didn't post, send the test cookie along with the login form.   
  22.     request.session.set_test_cookie()   
  23.     return render_to_response('foo/login_form.html')  

注意,內(nèi)建的登錄和注銷方法為你處理了這些

在視圖外使用sessions
內(nèi)部每個(gè)session只是在django.contrib.sessions.models定義的普通的Django模型,因?yàn)樗且粋(gè)普通模型,你可以使用
普通的Django數(shù)據(jù)庫API訪問sessions:
Java代碼 復(fù)制代碼
  1. >>> from django.contrib.sessions.models import Session   
  2. >>> s = Session.objects.get_object(pk='2b1189a188b44ad18c35e113ac6ceead')   
  3. >>> s.expire_date   
  4. datetime.datetime(2005820133512)  

你將需要調(diào)用get_decoded()來得到準(zhǔn)確的session數(shù)據(jù),這是必需的,因?yàn)樽值浯鎯?chǔ)為一個(gè)編碼的格式:
Java代碼 復(fù)制代碼
  1. >>> s.session_data   
  2. 'KGRwMQpTJ19hdXRoX3VzZXJfaWQnCnAyCkkxCnMuMTExY2ZjODI2Yj...'  
  3. >>> s.get_decoded()   
  4. {'user_id'42}  


當(dāng)sessions保存時(shí)
當(dāng)session修改后Django默認(rèn)只保存到session數(shù)據(jù)庫,即當(dāng)它的字典值被賦值或刪除時(shí):
Java代碼 復(fù)制代碼
  1. # Session is modified.   
  2. request.session['foo'] = 'bar'  
  3.   
  4. # Session is modified.   
  5. del request.session['foo']   
  6.   
  7. # Session is modified.   
  8. request.session['foo'] = {}   
  9.   
  10. # Gotcha: Session is NOT modified, because this alters   
  11. # request.session['foo'] instead of request.session.   
  12. request.session['foo']['bar'] = 'baz'  

為了更改這個(gè)默認(rèn)的行為,需要設(shè)置SESSION_SAVE_EVERY_REQUEST設(shè)置為True,如果SESSION_SAVE_EVERY_REQUEST為True
Django將在每個(gè)單獨(dú)的請(qǐng)求保存session到數(shù)據(jù)庫,設(shè)置當(dāng)它沒有改變時(shí)
注意只有當(dāng)session被創(chuàng)建或修改時(shí)session cookie才被發(fā)送,如果SESSION_SAVE_EVERY_REQUEST為True,session
cookie將對(duì)每次請(qǐng)求發(fā)送
同樣,session cookie的expires部分在每次session cookie發(fā)送時(shí)更新

瀏覽器長度的sessions與持久化sessions
你可能已經(jīng)注意到Google發(fā)送的cookie包含expires=Sun, 17-Jan-2038 19:14:07 GMT; Cookies可以可選的包含一個(gè)過期
日期,該日期告訴瀏覽器什么時(shí)候刪除cookie,如果一個(gè)cookie不包含過期值,瀏覽器將在用戶關(guān)閉瀏覽器窗口時(shí)過期
你可以通過SESSION_EXPIRE_AT_BROWSER_CLOSE設(shè)置來控制session框架在這點(diǎn)上的行為
SESSION_EXPIRE_AT_BROWSER_CLOSE默認(rèn)設(shè)置為False,這意味著session cookies將存儲(chǔ)在用戶的瀏覽器中持續(xù)
SESSION_COOKIE_AGE秒(默認(rèn)為兩星期,即1209600秒),如果你不想人們每次打開瀏覽器時(shí)都不得不登錄的話可以使用它
如果SESSION_EXPIRE_AT_BROWSER_CLOSE設(shè)置為True,Django將使用瀏覽器長度的cookies

其它session設(shè)置
除了已經(jīng)提到的設(shè)置,還有一些其它影響Django的session框架使用cookies的設(shè)置:
Setting                    Default        Explanation
SESSION_COOKIE_DOMAIN      None           session cookies使用的域名,設(shè)置它為一個(gè)字符串,如".lawrence.com"
                                          來使用跨域名的cookies,或者設(shè)置None來使用標(biāo)準(zhǔn)cookie
SESSION_COOKIE_NAME        "sessionid"    使用sessions 的cookie名,可以是任意字符串
SESSION_COOKIE_SECURE      False          session cookie是否使用"安全"cookie,如果設(shè)置為True,cookie將被
                                          標(biāo)記為"安全",這意味著瀏覽器將保證cookie只通過HTTPS傳送
技術(shù)細(xì)節(jié)
出于好奇,這里有一些關(guān)于session框架內(nèi)部工作的技術(shù)注解:
1,session字典接受任意pickleable Python對(duì)象,參考Python內(nèi)建的pickle模塊文檔得到更多關(guān)于這怎樣工作的信息
2,Session數(shù)據(jù)存儲(chǔ)在名為django_session的數(shù)據(jù)庫表中
3,Session數(shù)據(jù)是"lazily":如果你從不訪問request.session,Django不會(huì)接觸那個(gè)數(shù)據(jù)庫表
4,Django只在需要時(shí)傳送cookie,如果你不設(shè)置任何session數(shù)據(jù),它將不會(huì)發(fā)送session cookie(除非SESSION_SAVE_
EVERY_REQUEST設(shè)置為True)
5,Django的sessions框架是完整的,單獨(dú)的和基于cookie的,它不像其它工具(PHP,JSP)一樣求諸于把session IDs放在
URLs中
如果你仍然很好奇,源代碼是非常直接的,你可以查看django.contrib.sessions

用戶和認(rèn)證
現(xiàn)在我們將瀏覽器和真實(shí)的人連接起來已經(jīng)完成了一半,Sessions提供我們?cè)诙酁g覽器請(qǐng)求之間存儲(chǔ)數(shù)據(jù)的一種方式,第
二個(gè)因素是使用這些sessions來讓用戶登錄,當(dāng)然,我們不能只信任用戶所說的他們是誰,所以我們將需要認(rèn)證它們
自然,Django提供工具來處理這個(gè)通常的任務(wù)(以及許多其它的),Django的用戶認(rèn)證系統(tǒng)處理用戶,組,權(quán)限和基于
cookie的用戶sessions,這個(gè)系統(tǒng)通常稱為"認(rèn)證/授權(quán)"系統(tǒng),這個(gè)名字解釋了用戶通常分兩個(gè)步驟處理:
1,驗(yàn)證(認(rèn)證)用戶是她宣稱的人(通常通過對(duì)數(shù)據(jù)庫檢查用戶名和密碼)
2,驗(yàn)證用戶授權(quán)處理一些操作(通常檢查權(quán)限表)
遵循這些需要,Django的認(rèn)證/授權(quán)系統(tǒng)由一些部分組成:
1,Users
2,Permissions:二元(yes/no)標(biāo)記來指示用戶是否可以處理某一任務(wù)
3,Groups:把標(biāo)簽和權(quán)限賦予超過一個(gè)用戶的通常的方式
4,Messages:排入隊(duì)列和顯示用戶的系統(tǒng)消息的簡單方式
5,Profiles:用自定義域擴(kuò)展用戶對(duì)象的機(jī)制
如果你已經(jīng)使用了admin工具(第6章),你已經(jīng)看到許多這些工具,并且如果你在admin中編輯了用戶或組你事實(shí)上已經(jīng)在
編輯認(rèn)證系統(tǒng)的數(shù)據(jù)庫表

安裝
類似于session工具,認(rèn)證支持在django.contrib中綁定為Django程序,它需要安裝,像session系統(tǒng)一樣它默認(rèn)已經(jīng)被
安裝,但是如果你刪除了它,你將需要遵循這些步驟來安裝它:
1,確認(rèn)session框架安裝了(參考上面的內(nèi)容),跟蹤用戶顯然需要cookies,并且構(gòu)建在session框架之上
2,把'django.contrib.auth'放到你的INSTALLED_APPS設(shè)置中并運(yùn)行manage.py syncdb
3,確認(rèn)'django.contrib.auth.middleware.AuthenticationMiddleware'在你的MIDDLEWARE_CLASSES設(shè)置中,并且它在
SessionMiddleware之后
擁有了這些安裝,我們已經(jīng)可以在視圖方法中處理用戶,你將在視圖中使用來訪問用戶的主要接口是request.user,它是
一個(gè)表示當(dāng)前登錄的用戶的對(duì)象,如果用戶沒有登錄,它將被替代為一個(gè)AnonymousUser對(duì)象(參考下面更多細(xì)節(jié))
你可以使用is_authenticated()方法很輕松的分辨用戶是否登錄:
Java代碼 復(fù)制代碼
  1. if request.user.is_authenticated():   
  2.     # Do something for authenticated users.   
  3. else:   
  4.     # Do something for anonymous users.  


使用用戶
一旦你擁有一個(gè)用戶--通常從request.user得到,但也可能通過下面討論的一個(gè)其它方法得到--你已經(jīng)得到該對(duì)象的一些
域和方法,AnonymousUser對(duì)象仿效其中一些域和方法,但是不全,所以你應(yīng)該在你確認(rèn)處理的是真實(shí)的用戶對(duì)象之前一
直檢查user.is_authenticated()
User對(duì)象的域
Field            Description
username         必需的,30個(gè)字符或更少,只允許文字和數(shù)字字符(字母,數(shù)字和下劃線)
first_name       可選,30個(gè)字符或更少
last_name        可選,30個(gè)字符或更少
email            可選,E-mail地址
password         必需的,哈希的元數(shù)據(jù)秘密(Django不存儲(chǔ)原始密碼),參看下面的"密碼"部分得到更多關(guān)于這個(gè)值
is_staff         布爾值,指示用戶是否可以訪問admin站點(diǎn)
is_active        布爾值,指示用戶是否可以登錄,把這個(gè)標(biāo)記設(shè)置為False而不是刪除用戶
is_superuser     布爾值,指示用戶是否擁有所有的權(quán)限而不用顯示的賦予它們
last_login       用戶最后登錄的datetime,默認(rèn)設(shè)置為當(dāng)前date/time
date_joined      當(dāng)用戶創(chuàng)建時(shí)的datetime,當(dāng)用戶創(chuàng)建時(shí)默認(rèn)設(shè)置為當(dāng)前date/time
User對(duì)象的方法
Method                   Description
is_authenticated()       對(duì)"真實(shí)的"User對(duì)象一直返回True,這是分辨用戶是否認(rèn)證的方式,它不暗示任何權(quán)限,并且
                         不檢查用戶是否active,它只指示用戶成功認(rèn)證
is_anonymous()           只對(duì)AnonymousUser對(duì)象返回True(對(duì)"真實(shí)"User對(duì)象返回False),通常你應(yīng)該選擇使用
                         is_authenticated()方法而不是這個(gè)方法
get_full_name()          返回first_name加上last_name,使用一個(gè)空格間隔
set_password(passwd)     設(shè)置用戶的密碼為給定的原始密碼,它會(huì)處理密碼哈希,這事實(shí)上不會(huì)保存User對(duì)象
check_password(passwd)   如果給定的原始密碼是該用戶的正確的密碼則返回True,這會(huì)在比較時(shí)處理密碼哈希
get_group_permissions()  從用戶所屬的組返回用戶擁有的權(quán)限字符串的列表
get_all_permissions()    從用戶所屬的組和用戶的權(quán)限返回用戶擁有的全息字符串的列表
has_perm(perm)           如果用戶擁有該特殊權(quán)限則返回True,perm的格式為"package.codename",如果用戶inactive
                         該方法將一直返回False
has_perms(perm_list)     如果用戶擁有這些特殊權(quán)限則返回True,如果用戶為inactive,該方法將一直返回False
has_module_perms(appname)如果用戶擁有給定appname的任一權(quán)限則返回True,如果用戶inactive則一直返回False
get_and_delete_messages()返回用戶的隊(duì)列中的Message對(duì)象列表并從隊(duì)列中刪除消息
email_user(subj, msg)    發(fā)送一個(gè)e-mail給用戶,這個(gè)email從DEFAULT_FROM_EMAIL設(shè)置發(fā)送,你也可以傳遞第3個(gè)參數(shù)
                         from_email來覆蓋email的發(fā)送地址
get_profile()            返回站點(diǎn)特有的用戶的輪廓,參考下面的輪廓部分得到更多關(guān)于此方法
最后,User對(duì)象由兩個(gè)多對(duì)多域,groups和permissions,User對(duì)象可以像其它多對(duì)多域一樣訪問它們相關(guān)的對(duì)象:
Java代碼 復(fù)制代碼
  1. # Set a users groups:   
  2. myuser.groups = group_list   
  3.   
  4. # Add a user to some groups:   
  5. myuser.groups.add(group1, group2,...)   
  6.   
  7. # Remove a user from some groups:   
  8. myuser.groups.remove(group1, group2,...)   
  9.   
  10. # Remove a user from all groups:   
  11. myuser.groups.clear()   
  12.   
  13. # Permissions work the same way   
  14. myuser.permissions = permission_list   
  15. myuser.permissions.add(permission1, permission2, ...)   
  16. myuser.permissions.remove(permission1, permission2, ...)   
  17. myuser.permissions.clear()  


登錄和注銷
Django提供內(nèi)建的視圖方法來處理登錄和注銷(以及一些其它的好技巧),但現(xiàn)在先讓我們看看怎樣"手動(dòng)"登錄和注銷用戶
Django在django.contrib.auth中提供兩個(gè)方法來處理這些動(dòng)作:authenticate()和login()
使用authenticate()來認(rèn)證給定的用戶名和密碼,它有兩個(gè)關(guān)鍵字參數(shù),username和password,并且如果密碼是合法的則
它返回一個(gè)User對(duì)象,如果密碼不合法,authenticate()返回None:
Java代碼 復(fù)制代碼
  1. >>> from django.contrib import auth authenticate   
  2. >>> user = auth.authenticate(username='john', password='secret')   
  3. >>> if user is not None:   
  4. ...     print "Correct!"  
  5. ... else:   
  6. ...     print "Oops, that's wrong!"  
  7. Oops, that's wrong!  

在視圖中使用login()來登錄用戶,它使用一個(gè)HttpRequest對(duì)象和一個(gè)User對(duì)象并使用Django的session框架在session中
保存用戶的ID
這個(gè)例子展示了你怎樣在視圖方法中使用authenticate()和login():
Java代碼 復(fù)制代碼
  1. from django.contrib import auth   
  2.   
  3. def login(request):   
  4.     username = request.POST['username']   
  5.     password = request.POST['password']   
  6.     user = auth.authenticate(username=username, password=password)   
  7.     if user is not None and user.is_active:   
  8.         # Correct password, and the user is marked "active"  
  9.         auth.login(request, user)   
  10.         # Redirect to a success page.   
  11.         return HttpResponseRedirect("/account/loggedin/")   
  12.     else:   
  13.         # Show an error page   
  14.         return HttpResponseRedirect("/account/invalid/")  

在你的視圖中使用django.contrib.auth.logout()來注銷登錄的用戶,它使用一個(gè)HttpRequest對(duì)象并且沒有返回值:
Java代碼 復(fù)制代碼
  1. from django.contrib import auth   
  2.   
  3. def logout(request):   
  4.     auth.logout(request)   
  5.     # Redirect to a success page.   
  6.     return HttpResponseRedirect("/account/loggedout/")  

注意如果用戶沒有登錄的話logout()不會(huì)拋出任何異常
簡單方式的登錄和注銷
實(shí)踐中,你通常不需要寫你自己的登錄/注銷方法,auth系統(tǒng)帶有一套視圖來處理登錄和注銷
使用認(rèn)證視圖的第一步是修改你的URL配置,你將需要添加這些內(nèi)容:
Java代碼 復(fù)制代碼
  1. from django.contrib.auth.views import login, logout   
  2.   
  3. urlpatterns = patterns('',   
  4.     # existing patterns here...   
  5.     (r'^accounts/login/$',  login)   
  6.     (r'^accounts/logout/$', logout)   
  7. )  

/accounts/login/和/accounts/logout/是Django默認(rèn)為這些視圖使用的URLs,但是你做出一點(diǎn)努力就可以把它們放在任
何你想要的位置,login視圖默認(rèn)渲染registration/login.html視圖(你可以通過傳遞一個(gè)額外的視圖參數(shù)template_na
me更改這個(gè)模板名),這個(gè)表單需要包含一個(gè)用戶名和密碼域,一個(gè)簡單的模板可能看起來像這樣:
Java代碼 復(fù)制代碼
  1. {% extends "base.html" %}   
  2.   
  3. {% block content %}   
  4.   
  5.   {% if form.errors %}   
  6.     <p class="error">Sorry, that's not a valid username or password</p>   
  7.   {% endif %}   
  8.   
  9.   <form action='.' method='post'>   
  10.     <label for="username">User name:</label>   
  11.     <input type="text" name="username" value="" id="username">   
  12.     <label for="password">Password:</label>   
  13.     <input type="password" name="password" value="" id="password">   
  14.   
  15.     <input type="submit" value="login" />   
  16.     <input type="hidden" name="next" value="{{ next }}" />   
  17.   <form action='.' method='post'>   
  18.   
  19. {% endblock %}  

如果用戶成功登錄,她將默認(rèn)被重定向到/accounts/profile/,你可以通過提供一個(gè)叫next的在登錄之后重定向的URL值
的hidden域來覆蓋它,你也可以使用GET參數(shù)傳遞這個(gè)值到login視圖,它將作為叫next的變量被自動(dòng)添加到context中
注銷視圖工作起來有一點(diǎn)不同,默認(rèn)它渲染registration/logged_out.html模板(它通常包含一個(gè)"你已經(jīng)成功注銷"的信
息),盡管如此,你可以通過一個(gè)額外參數(shù)next_page來調(diào)用視圖,它將告訴視圖在注銷后重定向

限制登錄的用戶訪問
當(dāng)然,我們經(jīng)歷這些麻煩是為了使我們可以限制訪問我們站點(diǎn)的一部分
最簡單最原始的限制訪問頁面的方式是檢查request.user.is_authenticated()并重定向到登錄頁面:
Java代碼 復(fù)制代碼
  1. from django.http import HttpResponseRedirect   
  2.   
  3. def my_view(request):   
  4.     if not request.user.is_authenticated():   
  5.         return HttpResponseRedirect('/login/?next=%s' % request.path)   
  6.     # ...  

或者顯示一條出錯(cuò)信息:
Java代碼 復(fù)制代碼
  1. def my_view(request):   
  2.     if not request.user.is_au
    安徽新華電腦學(xué)校專業(yè)職業(yè)規(guī)劃師為你提供更多幫助【在線咨詢
日韩欧美一二三区| 日韩中文字幕一区| 午夜久久网| 国产伦久视频免费观看视频| 成人a级高清视频在线观看| 日本特黄特色aaa大片免费| 91麻豆tv| 亚洲精品中文一区不卡| 日韩在线观看免费| 日韩在线观看视频黄| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 日本特黄特色aaa大片免费| 午夜久久网| 黄视频网站在线免费观看| 青青久久国产成人免费网站| 精品国产一区二区三区国产馆| 四虎影视库国产精品一区| 欧美大片a一级毛片视频| 夜夜操天天爽| 欧美大片毛片aaa免费看| 久久精品道一区二区三区| 久久成人综合网| 九九精品影院| 日本特黄特色aaa大片免费| 成人免费观看的视频黄页| 青青久久网| 一级毛片看真人在线视频| 久久久成人影院| 精品美女| 国产亚洲免费观看| 国产高清在线精品一区二区| 国产精品免费精品自在线观看| 精品视频免费看| 91麻豆精品国产高清在线| 欧美a免费| 午夜精品国产自在现线拍| 久久国产精品自由自在| 精品久久久久久影院免费| 欧美激情一区二区三区视频| 国产91精品一区| 天堂网中文在线| 国产不卡在线看| 国产不卡在线播放| 欧美国产日韩在线| 韩国妈妈的朋友在线播放| 黄色福利片| 日本特黄特色aaa大片免费| 久草免费在线色站| 99热热久久| 韩国三级香港三级日本三级la| 成人免费网站视频ww| 免费国产在线观看不卡| 99热热久久| 可以免费看污视频的网站| 二级特黄绝大片免费视频大片| 香蕉视频一级| 国产国语对白一级毛片| a级毛片免费全部播放| 九九久久国产精品| 免费的黄色小视频| 九九久久99| 二级特黄绝大片免费视频大片| 国产视频一区二区在线观看| 久久精品免视看国产明星| 999久久狠狠免费精品| 久久99中文字幕| 日韩中文字幕在线亚洲一区 | 成人影视在线观看| 日韩中文字幕在线播放| 成人a级高清视频在线观看| 国产不卡在线看| 亚洲爆爽| 国产成人女人在线视频观看 | 精品国产一区二区三区久久久狼| 香蕉视频一级| 成人高清护士在线播放| 国产伦久视频免费观看视频| 韩国毛片基地| 色综合久久天天综合观看| 日韩专区一区| 黄色短视频网站| 久久国产精品自由自在| 欧美α片无限看在线观看免费| 精品在线观看一区| 欧美激情一区二区三区在线 | 日韩专区一区| 国产成人精品综合| 精品在线观看一区| 国产成人精品综合| 青青青草影院| 国产视频一区在线| 国产欧美精品午夜在线播放| 日日日夜夜操| 99色播| 精品视频在线观看视频免费视频| 成人高清视频免费观看| 国产原创中文字幕| 中文字幕97| 亚洲天堂免费观看| 日韩欧美一二三区| 99久久精品国产国产毛片| 欧美a免费| 天天做人人爱夜夜爽2020 | 一级毛片看真人在线视频| 色综合久久手机在线| 久久99中文字幕| 韩国三级视频在线观看| 免费国产在线观看不卡| 韩国妈妈的朋友在线播放| 午夜欧美福利| 二级特黄绝大片免费视频大片| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 午夜欧美福利| 青青久久网| 欧美激情一区二区三区中文字幕| 黄视频网站在线免费观看| 在线观看成人网| 国产网站麻豆精品视频| 日本免费乱人伦在线观看| 久久99中文字幕| 免费国产一级特黄aa大片在线| 97视频免费在线| 成人免费观看的视频黄页| 日韩在线观看视频网站| 国产美女在线观看| 欧美另类videosbestsex高清| 欧美爱色| 精品视频在线看| 欧美1卡一卡二卡三新区| 色综合久久天天综合观看| 91麻豆国产级在线| 精品久久久久久中文字幕一区| 欧美日本免费| 国产一区免费在线观看| 黄色短视频网站| 亚洲精品中文一区不卡| 精品国产亚洲人成在线| 午夜久久网| 精品视频一区二区三区| 成人高清护士在线播放| 九九精品影院| 国产不卡精品一区二区三区| 色综合久久天天综线观看| 国产视频一区二区在线观看| 九九精品影院| 久久精品免视看国产明星| 99色视频在线观看| 九九精品影院| 国产伦精品一区二区三区无广告 | 欧美另类videosbestsex视频| 九九免费精品视频| 中文字幕一区二区三区 精品| 精品久久久久久影院免费| 日日夜夜婷婷| 精品视频一区二区三区| 黄视频网站在线观看| 精品视频在线看| 国产成人啪精品| 日本伦理黄色大片在线观看网站| 欧美日本韩国| 四虎久久影院| 亚洲 欧美 91| 九九免费精品视频| a级精品九九九大片免费看| 午夜欧美福利| 99色视频在线观看| 亚洲天堂在线播放| 国产一区国产二区国产三区| 91麻豆精品国产综合久久久| 久久国产影院| 日韩在线观看免费| 亚久久伊人精品青青草原2020| 天天色色色| 深夜做爰性大片中文| 亚洲 男人 天堂| 黄视频网站在线免费观看| 91麻豆精品国产自产在线| 精品美女| 国产精品1024永久免费视频| 在线观看成人网| 欧美另类videosbestsex高清| 超级乱淫黄漫画免费| 日韩欧美一二三区| 亚欧视频在线| 免费国产一级特黄aa大片在线| 欧美激情一区二区三区在线 | 黄视频网站在线观看| 国产麻豆精品视频| 亚洲 欧美 91| 你懂的国产精品| 成人a大片高清在线观看| 国产91精品一区| 一本高清在线| 国产成a人片在线观看视频| 精品视频免费看| 九九九国产| 午夜精品国产自在现线拍| 成人免费观看网欧美片| 日本免费乱人伦在线观看| 国产麻豆精品hdvideoss|