<source id="4vppl"><ins id="4vppl"></ins></source>
<u id="4vppl"><sub id="4vppl"><label id="4vppl"></label></sub></u>
<object id="4vppl"></object>
  • <u id="4vppl"><li id="4vppl"><label id="4vppl"></label></li></u>

    <object id="4vppl"></object>
    <b id="4vppl"><sub id="4vppl"><tr id="4vppl"></tr></sub></b>

      <i id="4vppl"><thead id="4vppl"></thead></i>

      <thead id="4vppl"><li id="4vppl"><label id="4vppl"></label></li></thead>

      當前位置:首頁 > 網站舊欄目 > 學習園地 > 設計軟件教程 > 翻譯www.djangobook.com之第十二章:會話,用戶和注冊

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

      Cookies
      讓我們看看它可能怎樣工作,當你開啟瀏覽器并鍵入google.com,你的瀏覽器像這樣開始來發送一個HTTP請求到Google:
      GET / HTTP/1.1
      Host: google.com
      ...
      當Google回復時,HTTP應答看起來像這樣:
      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頭部,你的瀏覽器將存儲這個cookie值(PREF=ID=5b14f22bdaf1e81c:TM=1167000671:LM=1167000671)并在
      每次你訪問這個站點時回傳給Google,所以下一次你訪問Google時你的瀏覽器將傳遞像這樣的請求:
      GET / HTTP/1.1
      Host: google.com
      Cookie: PREF=ID=5b14f22bdaf1e81c:TM=1167000671:LM=1167000671
      ...
      然后Google可以使用這個Cookie值來知道你是早些時候訪問這個站點的同一個人
      例如,這個值可能是數據庫存儲用戶信息的鍵,Google可以(也確實)使用它來在頁面上顯示你的名字

      得到和設置cookies
      當在Django中處理持久化時,大部分時候你想使用稍后討論的高級session和/或用戶框架,盡管如此,我們將停下來先
      看看在Django中怎樣讀和寫cookies,它將幫助你理解本章其它部分事實上怎樣工作,并且如果你需要直接操作cookies
      的話它將觸手可得
      讀取已經設置的cookies是非常簡單的:每個request對象都有一個類似字典的COOKIES對象,你可以使用它來讀瀏覽器發送
      到視圖的任何cookies:
      Java代碼 復制代碼
      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更復雜一點,你需要使用HttpResponse對象的set_cookie()方法,這里是一個基于GET參數設置favorite_color
      cookie的例子:
      Java代碼 復制代碼
      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.")  

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

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

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

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

      在視圖里使用sessions
      當SessionMiddleware激活后,每個HttpRequest對象--每個Django視圖方法的第一個參數--將有一個session屬性,它是
      一個類似字典的對象,你可以像使用普通的字典一樣讀寫它,例如,你可以在視圖中做這樣的事情:
      Java代碼 復制代碼
      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的簡單規則:
      1,在request.session使用普通的Python字符串作為字典的鍵(而不是integers,objects等等),這是一個慣例,但是值
      得遵循
      2,以下劃線開始的session字典鍵被Django保留作內部使用,實踐中框架只使用非常少的下劃線前綴的session變量,但
      是除非你知道它們都是些什么(并且想跟上Django本身的更改),最好遠離它們以防Django妨礙你的app
      3,不要用新的對象覆蓋request.session,并且不要訪問或者設置它的屬性,像Python字典一樣使用它
      讓我們看看一些快速的例子,簡單的視圖在用戶提交一個comment后設置一個has_commented變量為True,它不讓一個用戶
      提交一個comment多于一次:
      Java代碼 復制代碼
      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!')  

      簡單的視圖在站點登錄一個"成員":
      Java代碼 復制代碼
      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.")  

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

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

      設置測試cookies
      上面提到,你不能依賴每個瀏覽器接受cookies,所以,為了方便起見,Django提供了一個簡單的方式來測試用戶的瀏覽器
      是否接受cookies,你只需在視圖中調用request.session.set_test_cookie()并在后面的視圖中檢查requet.session.test
      _cookie_worked(),而不是在同一個視圖中調用
      由于cookies的工作方式,這樣笨拙的分離set_test_cookie()和test_cookie_worked()很必要,當你設置一個cookie,你
      事實上不能分辨瀏覽器是否接受它,直到瀏覽器下一次請求
      你自己使用delete_test_cookie()來清除測試cookie是良好的實踐,在你驗證測試cookie工作后做這件事
      這里是一個典型的使用例子:
      Java代碼 復制代碼
      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')  

      注意,內建的登錄和注銷方法為你處理了這些

      在視圖外使用sessions
      內部每個session只是在django.contrib.sessions.models定義的普通的Django模型,因為它是一個普通模型,你可以使用
      普通的Django數據庫API訪問sessions:
      Java代碼 復制代碼
      1. >>> from django.contrib.sessions.models import Session   
      2. >>> s = Session.objects.get_object(pk='2b1189a188b44ad18c35e113ac6ceead')   
      3. >>> s.expire_date   
      4. datetime.datetime(2005820133512)  

      你將需要調用get_decoded()來得到準確的session數據,這是必需的,因為字典存儲為一個編碼的格式:
      Java代碼 復制代碼
      1. >>> s.session_data   
      2. 'KGRwMQpTJ19hdXRoX3VzZXJfaWQnCnAyCkkxCnMuMTExY2ZjODI2Yj...'  
      3. >>> s.get_decoded()   
      4. {'user_id'42}  


      當sessions保存時
      當session修改后Django默認只保存到session數據庫,即當它的字典值被賦值或刪除時:
      Java代碼 復制代碼
      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'  

      為了更改這個默認的行為,需要設置SESSION_SAVE_EVERY_REQUEST設置為True,如果SESSION_SAVE_EVERY_REQUEST為True
      Django將在每個單獨的請求保存session到數據庫,設置當它沒有改變時
      注意只有當session被創建或修改時session cookie才被發送,如果SESSION_SAVE_EVERY_REQUEST為True,session
      cookie將對每次請求發送
      同樣,session cookie的expires部分在每次session cookie發送時更新

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

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

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

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


      使用用戶
      一旦你擁有一個用戶--通常從request.user得到,但也可能通過下面討論的一個其它方法得到--你已經得到該對象的一些
      域和方法,AnonymousUser對象仿效其中一些域和方法,但是不全,所以你應該在你確認處理的是真實的用戶對象之前一
      直檢查user.is_authenticated()
      User對象的域
      Field            Description
      username         必需的,30個字符或更少,只允許文字和數字字符(字母,數字和下劃線)
      first_name       可選,30個字符或更少
      last_name        可選,30個字符或更少
      email            可選,E-mail地址
      password         必需的,哈希的元數據秘密(Django不存儲原始密碼),參看下面的"密碼"部分得到更多關于這個值
      is_staff         布爾值,指示用戶是否可以訪問admin站點
      is_active        布爾值,指示用戶是否可以登錄,把這個標記設置為False而不是刪除用戶
      is_superuser     布爾值,指示用戶是否擁有所有的權限而不用顯示的賦予它們
      last_login       用戶最后登錄的datetime,默認設置為當前date/time
      date_joined      當用戶創建時的datetime,當用戶創建時默認設置為當前date/time
      User對象的方法
      Method                   Description
      is_authenticated()       對"真實的"User對象一直返回True,這是分辨用戶是否認證的方式,它不暗示任何權限,并且
                               不檢查用戶是否active,它只指示用戶成功認證
      is_anonymous()           只對AnonymousUser對象返回True(對"真實"User對象返回False),通常你應該選擇使用
                               is_authenticated()方法而不是這個方法
      get_full_name()          返回first_name加上last_name,使用一個空格間隔
      set_password(passwd)     設置用戶的密碼為給定的原始密碼,它會處理密碼哈希,這事實上不會保存User對象
      check_password(passwd)   如果給定的原始密碼是該用戶的正確的密碼則返回True,這會在比較時處理密碼哈希
      get_group_permissions()  從用戶所屬的組返回用戶擁有的權限字符串的列表
      get_all_permissions()    從用戶所屬的組和用戶的權限返回用戶擁有的全息字符串的列表
      has_perm(perm)           如果用戶擁有該特殊權限則返回True,perm的格式為"package.codename",如果用戶inactive
                               該方法將一直返回False
      has_perms(perm_list)     如果用戶擁有這些特殊權限則返回True,如果用戶為inactive,該方法將一直返回False
      has_module_perms(appname)如果用戶擁有給定appname的任一權限則返回True,如果用戶inactive則一直返回False
      get_and_delete_messages()返回用戶的隊列中的Message對象列表并從隊列中刪除消息
      email_user(subj, msg)    發送一個e-mail給用戶,這個email從DEFAULT_FROM_EMAIL設置發送,你也可以傳遞第3個參數
                               from_email來覆蓋email的發送地址
      get_profile()            返回站點特有的用戶的輪廓,參考下面的輪廓部分得到更多關于此方法
      最后,User對象由兩個多對多域,groups和permissions,User對象可以像其它多對多域一樣訪問它們相關的對象:
      Java代碼 復制代碼
      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提供內建的視圖方法來處理登錄和注銷(以及一些其它的好技巧),但現在先讓我們看看怎樣"手動"登錄和注銷用戶
      Django在django.contrib.auth中提供兩個方法來處理這些動作:authenticate()和login()
      使用authenticate()來認證給定的用戶名和密碼,它有兩個關鍵字參數,username和password,并且如果密碼是合法的則
      它返回一個User對象,如果密碼不合法,authenticate()返回None:
      Java代碼 復制代碼
      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()來登錄用戶,它使用一個HttpRequest對象和一個User對象并使用Django的session框架在session中
      保存用戶的ID
      這個例子展示了你怎樣在視圖方法中使用authenticate()和login():
      Java代碼 復制代碼
      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()來注銷登錄的用戶,它使用一個HttpRequest對象并且沒有返回值:
      Java代碼 復制代碼
      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()不會拋出任何異常
      簡單方式的登錄和注銷
      實踐中,你通常不需要寫你自己的登錄/注銷方法,auth系統帶有一套視圖來處理登錄和注銷
      使用認證視圖的第一步是修改你的URL配置,你將需要添加這些內容:
      Java代碼 復制代碼
      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默認為這些視圖使用的URLs,但是你做出一點努力就可以把它們放在任
      何你想要的位置,login視圖默認渲染registration/login.html視圖(你可以通過傳遞一個額外的視圖參數template_na
      me更改這個模板名),這個表單需要包含一個用戶名和密碼域,一個簡單的模板可能看起來像這樣:
      Java代碼 復制代碼
      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 %}  

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

      限制登錄的用戶訪問
      當然,我們經歷這些麻煩是為了使我們可以限制訪問我們站點的一部分
      最簡單最原始的限制訪問頁面的方式是檢查request.user.is_authenticated()并重定向到登錄頁面:
      Java代碼 復制代碼
      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.     # ...  

      或者顯示一條出錯信息:
      Java代碼 復制代碼
      1. def my_view(request):   
      2.     if not request.user.is_au
        安徽新華電腦學校專業職業規劃師為你提供更多幫助【在線咨詢
      国产午夜福三级在线播放_亚洲精品成a人片在线观看_亚洲自慰一区二区三区_久久棈精品久久久久久噜噜
      <source id="4vppl"><ins id="4vppl"></ins></source>
      <u id="4vppl"><sub id="4vppl"><label id="4vppl"></label></sub></u>
      <object id="4vppl"></object>
    1. <u id="4vppl"><li id="4vppl"><label id="4vppl"></label></li></u>

      <object id="4vppl"></object>
      <b id="4vppl"><sub id="4vppl"><tr id="4vppl"></tr></sub></b>

        <i id="4vppl"><thead id="4vppl"></thead></i>

        <thead id="4vppl"><li id="4vppl"><label id="4vppl"></label></li></thead>
        综合激情亚洲丁香社区 | 新婚少妇真紧视频 | 亚洲国产精品久久久久柚木 | 日韩国产一区二区 | 永久免费的污网站在线观看 | 亚洲丝袜一区二区三区 |