乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Django 教程 8: 用戶授權(quán)與許可

       寧靜致遠(yuǎn)oj1kn5 2019-06-13

      在本教程中,我們將向您展示如何允許用戶使用自己的帳戶登錄到您的網(wǎng)站,以及如何根據(jù)用戶是否已登錄及其權(quán)限來控制他們可以執(zhí)行和查看的內(nèi)容。作為演示的一部分,我們將擴(kuò)展LocalLibrary網(wǎng)站,添加登錄頁面和注銷頁面,以及用戶和員工特定的頁面以查看已借閱的圖書。

      先決條件: 完成之前的所有教程主題,包括Django 教程 7:Sessions 框架。
      目的: 了解如何設(shè)置和使用用戶身份驗(yàn)證和權(quán)限。

      概觀節(jié)

      Django 提供了一個(gè)身份驗(yàn)證和授權(quán)(“權(quán)限”)系統(tǒng),該系統(tǒng)構(gòu)建在上一個(gè)教程中討論的會話框架之上,允許您驗(yàn)證用戶憑據(jù),并定義每個(gè)用戶可允許執(zhí)行的操作。該框架包括用戶Users和分組Groups的內(nèi)置模型(一次向多個(gè)用戶應(yīng)用權(quán)限的通用方法),用于登錄用戶的權(quán)限/標(biāo)志,以指定用戶是否可以執(zhí)行任務(wù),表單和視圖,以及查看限制內(nèi)容的工具。

      注意: Django身份驗(yàn)證系統(tǒng)的目標(biāo)非常通用,因此不提供其他Web身份驗(yàn)證系統(tǒng)中,所提供的某些功能。某些常見問題的解決方案,可作為第三方軟件包提供。例如,限制登錄嘗試,和針對第三方的身份驗(yàn)證(例如 OAuth)。

      在本教程中,我們將向您展示,如何在LocalLibrary網(wǎng)站中,啟用用戶身份驗(yàn)證,創(chuàng)建您自己的登錄和注銷頁面,為模型添加權(quán)限,以及控制對頁面的訪問。我們將使用身份驗(yàn)證/權(quán)限,來顯示用戶和圖書館員借用圖書的列表。

      身份驗(yàn)證系統(tǒng)非常靈活,您可以根據(jù)需要,從頭開始構(gòu)建 URLs,表單,視圖和模板,只需調(diào)用提供的API,即可登錄用戶。但是,在本文中,我們將在登錄和注銷頁面,使用 Django 的“庫存” 身份驗(yàn)證視圖和表單。我們?nèi)匀恍枰獎(jiǎng)?chuàng)建一些模板,但這很簡單。

      我們還將向您展示如何創(chuàng)建權(quán)限,以及檢查視圖和模板中的登錄狀態(tài)和權(quán)限。

      啟用身份驗(yàn)證節(jié)

      我們在創(chuàng)建框架網(wǎng)站時(shí)(在教程2中),自動(dòng)啟用了身份驗(yàn)證,因此您此時(shí),無需再執(zhí)行任何操作。

      注意: 當(dāng)我們使用 django-admin startproject 命令,以創(chuàng)建應(yīng)用程序時(shí),所有必要的配置都已完成。當(dāng)我們第一次調(diào)用 python manage.py migrate 時(shí),創(chuàng)建了用戶和模型權(quán)限的數(shù)據(jù)庫表。

      配置在項(xiàng)目文件(locallibrary/locallibrary/settings.py)的INSTALLED_APPSMIDDLEWARE部分中設(shè)置,如下所示:

      INSTALLED_APPS = [
          ...
          'django.contrib.auth',  #Core authentication framework and its default models.
          'django.contrib.contenttypes',  #Django content type system (allows permissions to be associated with models).
          ....
      
      MIDDLEWARE = [
          ...
          'django.contrib.sessions.middleware.SessionMiddleware',  #Manages sessions across requests
          ...
          'django.contrib.auth.middleware.AuthenticationMiddleware',  #Associates users with requests using sessions.
          ....

      創(chuàng)建用戶和分組節(jié)

      在教程 4 中,當(dāng)我們查看 Django 管理站點(diǎn)時(shí),您已經(jīng)創(chuàng)建了第一個(gè)用戶(這是一個(gè)超級用戶,使用命令 python manage.py createsuperuser 創(chuàng)建)。我們的超級用戶已經(jīng)過身份驗(yàn)證,并擁有所有權(quán)限,因此我們需要?jiǎng)?chuàng)建一個(gè)測試用戶,來代表普通網(wǎng)站用戶。我們將使用管理站點(diǎn),來創(chuàng)建我們的 locallibrary 組別和網(wǎng)站登錄,因?yàn)檫@是最快的方法之一。

      注意: 您還可以用編程方式創(chuàng)建用戶,如下所示。您會必須這樣做,例如,如果要開發(fā)一個(gè)界面,能允許用戶創(chuàng)建自己的登錄(您不應(yīng)該授予用戶訪問管理站點(diǎn)的權(quán)限)。

      from django.contrib.auth.models import User
      
      # Create user and save to the database
      user = User.objects.create_user('myusername', 'myemail@crazymail.com', 'mypassword')
      
      # Update fields and then save again
      user.first_name = 'John'
      user.last_name = 'Citizen'
      user.save()

      下面,我們首先創(chuàng)建一個(gè)分組,然后創(chuàng)建一個(gè)用戶。即使我們還沒有為我們的圖書館成員添加任何權(quán)限,如果我們以后需要,將它們添加到分組中,要比單獨(dú)添加到每個(gè)成員要容易得多。

      啟動(dòng)開發(fā)服務(wù)器,并到本地 Web 瀏覽器中的管理站點(diǎn)(http://127.0.0.1:8000/admin/)。使用超級用戶帳戶的憑據(jù),登錄該站點(diǎn)。 Admin 站點(diǎn)的最上級顯示所有模型,按 “django application” 排序。在 “身份驗(yàn)證和授權(quán)” Authentication and Authorisation 部分 ,您可以單擊用戶 Users ,或分組 Groups 鏈接,以查看其現(xiàn)有記錄。

      Admin site - add groups or users

      首先,我們?yōu)閳D書館成員,創(chuàng)建一個(gè)新的分組。

      1. 單擊“添加” Add 按鈕(“分組” Group 旁邊)以創(chuàng)建新的分組;在分組的名稱 Name ,輸入“Library Members”。Admin site - add group
      2. 我們不需要該組的任何權(quán)限,因此只需按SAVE(您將進(jìn)入分組列表)。

      現(xiàn)在讓我們創(chuàng)建一個(gè)用戶:

      1. 回到管理站點(diǎn)的主頁
      2. 單擊“用戶”旁邊的“添加”按鈕 Add,以打開“添加用戶”對話框。Admin site - add user pt1
      3. 為測試用戶輸入適當(dāng)?shù)挠脩裘?strong>Username)和密碼/密碼確認(rèn)(Password/Password confirmation
      4. SAVE 創(chuàng)建用戶。

         

        管理站點(diǎn)將創(chuàng)建新用戶,并立即轉(zhuǎn)到 “更改用戶” 屏幕,您可以在其中更改用戶名(username),并添加用戶模型的可選字段的信息。這些字段包括名字,姓氏,電子郵件地址,用戶狀態(tài)和權(quán)限(僅應(yīng)設(shè)置活動(dòng)標(biāo)志 Active)。再往下,您可以指定用戶的分組和權(quán)限,并查看與用戶相關(guān)的重要日期(例如,他們的加入日期和上次登錄日期)。

        Admin site - add user pt2
      5. 在“分組”(Groups)部分中,從“可用分組”(Available groups)列表中,選擇“圖書館成員”分組 Library Member,然后點(diǎn)擊這些框之間的右箭頭,將其移動(dòng)到“選擇的分組”(Chosen groups)框中。Admin site - add user to group
      6. 我們不需要在此處執(zhí)行任何其他操作,因此只需再次選擇 SAVE ,即可轉(zhuǎn)到用戶列表。

      就是這樣!現(xiàn)在您有一個(gè) “普通的圖書館成員” 帳戶,您可以使用該帳戶進(jìn)行測試(一旦我們實(shí)現(xiàn)了頁面,使他們能夠登錄)。

      注意: 您應(yīng)該嘗試創(chuàng)建另一個(gè)圖書館用戶。此外,為圖書館管理員創(chuàng)建一個(gè)分組,并添加一個(gè)用戶!

      設(shè)置身份驗(yàn)證視圖節(jié)

      Django 提供了創(chuàng)建身份驗(yàn)證頁面所需的幾乎所有功能,讓處理登錄,注銷和密碼管理等工作,都能 “開箱即用”。這些相關(guān)功能包括了 url 映射器,視圖和表單,但它不包括模板 - 我們必須創(chuàng)建自己的模板!

      在本節(jié)中,我們將展示如何將默認(rèn)系統(tǒng),集成到 LocalLibrary 網(wǎng)站并創(chuàng)建模板。我們將它們放在主項(xiàng)目的 URL 當(dāng)中。

      注意: 您不必一定要使用這些代碼,但您可能希望這樣做,因?yàn)樗故虑樽兊酶菀住H绻挠脩裟P停ǜ呒壷黝}?。鷰缀蹩隙ㄐ枰谋韱翁幚泶a。但即便如此,您仍然可以使用先前已經(jīng)有的視圖功能。

      注意: 在這種情況下,我們可以合理地將認(rèn)證頁面(包括URL和模板)放在我們的目錄應(yīng)用程序中。但是,如果我們有多個(gè)應(yīng)用程序,最好將這個(gè)共享登錄行為分開,并讓它在整個(gè)站點(diǎn)上可用,這就是我們在這里展示的內(nèi)容!

      項(xiàng)目網(wǎng)址節(jié)

      將以下內(nèi)容,添加到項(xiàng)目 urls.py(locallibrary/locallibrary/urls.py)文件的底部:

      # Use include() to add URLS from the catalog application and authentication system
      from django.urls import include
      
      #Add Django site authentication urls (for login, logout, password management)
      urlpatterns += [
          path('accounts/', include('django.contrib.auth.urls')),
      ]

      打開 URL http://127.0.0.1:8000/accounts/ (注意前面的斜杠!),Django將顯示一個(gè)錯(cuò)誤,它無法找到此URL,并列出它嘗試過的所有URL。從中您可以看到可以使用的URL,例如:

      注意: 使用上面的方法,添加以下帶有方括號中的名稱的 URL,可用于反轉(zhuǎn) URL 映射。您不必實(shí)現(xiàn)任何其他內(nèi)容 - 上面的 url 映射,會自動(dòng)映射下面提到的URL。

      accounts/ login/ [name='login']
      accounts/ logout/ [name='logout']
      accounts/ password_change/ [name='password_change']
      accounts/ password_change/done/ [name='password_change_done']
      accounts/ password_reset/ [name='password_reset']
      accounts/ password_reset/done/ [name='password_reset_done']
      accounts/ reset/<uidb64>/<token>/ [name='password_reset_confirm']
      accounts/ reset/done/ [name='password_reset_complete']

      現(xiàn)在嘗試打開登錄 URL(http://127.0.0.1:8000/accounts/login/)。這將再次失敗,但有一個(gè)錯(cuò)誤告訴您,我們在模板搜索路徑上缺少必需的模板(registration/login.html)。您將在頂部的黃色部分中,看到以下文字:

      Exception Type:    TemplateDoesNotExist
      Exception Value:    registration/login.html

      下一步是在搜索路徑上創(chuàng)建注冊目錄,然后添加 login.html 文件。

      模板目錄節(jié)

      我們希望在模板搜索路徑中的目錄 /registration/ 某處,找到剛剛添加的 url(以及隱式視圖)的關(guān)聯(lián)模板。

      對于此站點(diǎn),我們將 HTML 頁面,放在 templates/registration/ 目錄中。此目錄應(yīng)該位于項(xiàng)目的根目錄中,即與 catalog locallibrary 文件夾相同的目錄)。請立即創(chuàng)建這些文件夾。

      注意: 您的文件夾結(jié)構(gòu),現(xiàn)在應(yīng)如下所示:
      locallibrary (django project folder)
         |_catalog
         |_locallibrary
         |_templates (new)
                      |_registration

      要使這些目錄對模板加載器可見(即將此目錄放在模板搜索路徑中),請打開項(xiàng)目設(shè)置(/locallibrary/locallibrary/settings.py),并更新TEMPLATES 部分的 “DIRS” 那一行,如下所示。

      TEMPLATES = [
          {
              ...
              'DIRS': ['./templates',],
              'APP_DIRS': True,
              ...

      登錄模板節(jié)

      重要說明: 本文提供的身份驗(yàn)證模板,是 Django 演示登錄模板的基本/略微修改版本。您可能需要自定義它們,以供自己使用!

      創(chuàng)建一個(gè)名為 /locallibrary/templates/registration/login.html 的新HTML文件。為它加入以下內(nèi)容:

      {% extends "base_generic.html" %}
      
      {% block content %}
      
      {% if form.errors %}
      <p>Your username and password didn't match. Please try again.</p>
      {% endif %}
      
      {% if next %}
          {% if user.is_authenticated %}
          <p>Your account doesn't have access to this page. To proceed,
          please login with an account that has access.</p>
          {% else %}
          <p>Please login to see this page.</p>
          {% endif %}
      {% endif %}
      
      <form method="post" action="{% url 'login' %}">
      {% csrf_token %}
      
      <div>
        <td>{{ form.username.label_tag }}</td>
        <td>{{ form.username }}</td>
      </div>
      <div>
        <td>{{ form.password.label_tag }}</td>
        <td>{{ form.password }}</td>
      </div>
      
      <div>
        <input type="submit" value="login" />
        <input type="hidden" name="next" value="{{ next }}" />
      </div>
      </form>
      
      {# Assumes you setup the password_reset view in your URLconf #}
      <p><a href="{% url 'password_reset' %}">Lost password?</a></p>
      
      {% endblock %}

      此模板與我們之前看到的模板,有一些相似之處 - 它擴(kuò)展了我們的基本模板,并覆蓋了內(nèi)容區(qū)塊 content。其余代碼,是相當(dāng)標(biāo)準(zhǔn)的表單處理代碼,我們將在后面的教程中討論。您現(xiàn)在需要知道的是,這將顯示一個(gè)表單,您可以在其中輸入您的用戶名和密碼,如果您輸入的值無效,則會在頁面刷新時(shí),提示您輸入正確的值。

      保存模板后,回到登錄頁面(http://127.0.0.1:8000/accounts/login/),您應(yīng)該看到如下內(nèi)容:

      Library login page v1

      如果您嘗試登錄,將會成功,并且您將被重定向到另一個(gè)頁面(默認(rèn)情況下,這將是 http://127.0.0.1:8000/accounts/profile/)。這里的問題是,默認(rèn)情況下,Django希望在登錄后,你可能會被帶到個(gè)人資料頁面,這可能是,也可能不是。由于您還沒有定義此頁面,您將收到另一個(gè)錯(cuò)誤!

      打開項(xiàng)目設(shè)置(/locallibrary/locallibrary/settings.py),并將下面的文本添加到底部?,F(xiàn)在登錄時(shí),您應(yīng)該默認(rèn)重定向到站點(diǎn)主頁。

      # Redirect to home URL after login (Default redirects to /accounts/profile/)
      LOGIN_REDIRECT_URL = '/'

      登出模板節(jié)

      如果您打開登出網(wǎng)址(http://127.0.0.1:8000/accounts/logout/),那么您會看到一些奇怪的行為 - 您所屬的用戶肯定會被登出,但您將被帶到管理員登出頁面。這不是您想要的,只是因?yàn)樵擁撁嫔系牡卿涙溄?,將您帶到管理員登錄屏幕(并且僅對具有is_staff權(quán)限的用戶可用)。

      創(chuàng)建并打開 /locallibrary/templates/registration/logged_out.html。將下面的文字,復(fù)制到文檔中:

      {% extends "base_generic.html" %}
      
      {% block content %}
      <p>Logged out!</p>  
      
      <a href="{% url 'login'%}">Click here to login again.</a>
      {% endblock %}

      這個(gè)模板非常簡單。它只顯示一條消息,通知您已登出,并提供一個(gè)鏈接,您可以點(diǎn)擊此按鈕,返回登錄屏幕。如果再次回到登出 URL,您應(yīng)該看到此頁面:

      Library logout page v1

      密碼重置模板節(jié)

      默認(rèn)密碼重置系統(tǒng),使用電子郵件向用戶發(fā)送重置鏈接。您需要?jiǎng)?chuàng)建表單,以獲取用戶的電子郵件地址,發(fā)送電子郵件,允許他們輸入新密碼,以及記錄整個(gè)過程的完成時(shí)間。

      以下模板可作為起點(diǎn)。

      密碼重置表單

      這是用于獲取用戶電子郵件地址的表單(用于發(fā)送密碼重置電子郵件)。創(chuàng)建 /locallibrary/templates/registration/password_reset_form.html,并為其提供以下內(nèi)容:

      {% extends "base_generic.html" %}
      {% block content %}
      
      <form action="" method="post">{% csrf_token %}
          {% if form.email.errors %} {{ form.email.errors }} {% endif %}
              <p>{{ form.email }}</p> 
          <input type="submit" class="btn btn-default btn-lg" value="Reset password" />
      </form>
      
      {% endblock %}

      密碼重置完成

      收集您的電子郵件地址后,會顯示此表單。創(chuàng)建 /locallibrary/templates/registration/password_reset_done.html,并為其提供以下內(nèi)容:

      {% extends "base_generic.html" %}
      {% block content %}
      <p>We've emailed you instructions for setting your password. If they haven't arrived in a few minutes, check your spam folder.</p>
      {% endblock %}

      密碼重置電子郵件

      此模板提供 HTML 電子郵件的文本,其中包含我們將發(fā)送給用戶的重置鏈接。創(chuàng)建 /locallibrary/templates/registration/password_reset_email.html,并為其提供以下內(nèi)容:

      Someone asked for password reset for email {{ email }}. Follow the link below:
      {{ protocol}}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}

      密碼重置確認(rèn)

      點(diǎn)擊密碼重置電子郵件中的鏈接后,您可以在此頁面輸入新密碼。創(chuàng)建 /locallibrary/templates/registration/password_reset_confirm.html,并為其提供以下內(nèi)容:

      {% extends "base_generic.html" %}
      
      {% block content %}
      
          {% if validlink %}
              <p>Please enter (and confirm) your new password.</p>
              <form action="" method="post">
                  <div style="display:none">
                      <input type="hidden" value="{{ csrf_token }}" name="csrfmiddlewaretoken">
                  </div>
                  <table>
                      <tr>
                          <td>{{ form.new_password1.errors }}
                              <label for="id_new_password1">New password:</label></td>
                          <td>{{ form.new_password1 }}</td>
                      </tr>
                      <tr>
                          <td>{{ form.new_password2.errors }}
                              <label for="id_new_password2">Confirm password:</label></td>
                          <td>{{ form.new_password2 }}</td>
                      </tr>
                      <tr>
                          <td></td>
                          <td><input type="submit" value="Change my password" /></td>
                      </tr>
                  </table>
              </form>
          {% else %}
              <h1>Password reset failed</h1>
              <p>The password reset link was invalid, possibly because it has already been used. Please request a new password reset.</p>
          {% endif %}
      
      {% endblock %}

      密碼重置完成

      這是最后一個(gè)密碼重置模板,顯示該模板,以在密碼重置成功時(shí)通知您。創(chuàng)建 /locallibrary/templates/registration/password_reset_complete.html,并為其提供以下內(nèi)容:

      {% extends "base_generic.html" %}
      {% block content %}
      
      <h1>The password has been changed!</h1>
      <p><a href="{% url 'login' %}">log in again?</a></p>
      
      {% endblock %}

      測試新的身份驗(yàn)證頁面節(jié)

      現(xiàn)在您已經(jīng)添加了 URL 配置,并創(chuàng)建了所有模板,現(xiàn)在認(rèn)證頁面應(yīng)該可以正常工作了!

      您可以嘗試登錄,然后使用以下 URL 登出超級用戶帳戶,來測試新的身份驗(yàn)證頁面:

      您將能夠從登錄頁面中的鏈接,測試密碼重置功能。請注意,Django只會向已存儲在其數(shù)據(jù)庫中的地址(用戶)發(fā)送重置電子郵件!

      注意: 密碼重置系統(tǒng),要求您的網(wǎng)站支持電子郵件,這超出了本文的范圍,因此該部分將無法使用。要測試此功能,請將以下一行放在 settings.py 文件的末尾。這會記錄發(fā)送到命令行控制臺的所有電子郵件(因此您可以從命令行控制臺,復(fù)制密碼重置鏈接)。

      EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

      有關(guān)更多信息,請參閱發(fā)送電子郵件(Django文檔)。

      測試已驗(yàn)證身份的用戶節(jié)

      本節(jié)介紹如何根據(jù)用戶是否登錄,來有選擇地控制用戶看到的內(nèi)容。

      在模板中測試節(jié)

      您可以使用{{ user }}模板變量,以獲取有關(guān)模板中,當(dāng)前登錄用戶的信息(默認(rèn)情況下,在我們在骨架中設(shè)置項(xiàng)目時(shí),會將其添加到模板上下文中)。

      通常,您將首先針對 {{ user.is_authenticated }} 模板變量進(jìn)行測試,以確定用戶是否有資格查看特定內(nèi)容。為了展示這一點(diǎn),接下來我們將更新側(cè)邊欄,以在用戶登出時(shí),顯示“登錄”鏈接,如果他們已登錄,則顯示“登出”鏈接。

      打開基本模板(/locallibrary/catalog/templates/base_generic.html),并將以下文本,復(fù)制到側(cè)邊欄區(qū)塊sidebar中,緊接在endblock模板標(biāo)記之前。

      <ul class="sidebar-nav">
      
          ...
      
         {% if user.is_authenticated %}
           <li>User: {{ user.get_username }}</li>
           <li><a href="{% url 'logout'%}?next={{request.path}}">Logout</a></li>   
         {% else %}
           <li><a href="{% url 'login'%}?next={{request.path}}">Login</a></li>   
         {% endif %} 
        </ul>

      如您所見,我們使用 if-else-endif模板標(biāo)簽,根據(jù) {{ user.is_authenticated }} 是否為 true ,來有條件地顯示文本。如果用戶已通過身份驗(yàn)證,那么我們知道,我們擁有有效用戶,因此我們會調(diào)用 {{ user.get_username }} ,來顯示其名稱。

      我們使用 url模板標(biāo)記,和相應(yīng) URL 配置的名稱,創(chuàng)建登錄和登出鏈接 URL。另外請注意,我們?nèi)绾螌?“?next={{request.path}}附加到URL的末尾。這樣做,是將包含當(dāng)前頁面地址(URL)的URL參數(shù),添加到鏈接URL的末尾。用戶成功登錄/登出后,視圖將使用此“下一個(gè)”值,將用戶重定向,回到他們首次單擊登錄/登出鏈接的頁面。

      注意: 試試吧!如果您在主頁上,并單擊側(cè)欄中的“登錄/登出”,在操作完成后,您應(yīng)該返回到同一頁面。

      在視圖中測試節(jié)

      如果您正在使用基于函數(shù)的視圖,則限制訪問函數(shù)的最簡單方法,是將login_required裝飾器,應(yīng)用于您的視圖函數(shù),如下所示。如果用戶已登錄,則您的視圖代碼將正常執(zhí)行。

      如果用戶未登錄,則會重定向到項(xiàng)目設(shè)置 (settings.LOGIN_URL)中定義的登錄URL,并將當(dāng)前絕對路徑,作為URL參數(shù)("下一個(gè)"next)來傳遞。如果用戶成功登錄,則會返回到此頁面,但這次會進(jìn)行身份驗(yàn)證。

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

      注意: 您可以通過request.user.is_authenticated,測試手動(dòng)執(zhí)行類似的操作,但裝飾器更方便!

      同樣,在基于類別的視圖中,限制對登錄用戶的訪問的最簡單方法,是從LoginRequiredMixin派生。您需要在主視圖類之前的超類列表中,首先聲明此 mixin。

      from django.contrib.auth.mixins import LoginRequiredMixin
      
      class MyView(LoginRequiredMixin, View):
          ...

      這與login_required裝飾器,具有完全相同的重定向行為。如果用戶未經(jīng)過身份驗(yàn)證(login_url),還可以指定一個(gè)替代位置,以將用戶重定向到該位置,并使用URL參數(shù)名稱,而不是“next”,來插入當(dāng)前絕對路徑(redirect_field_name)。

      class MyView(LoginRequiredMixin, View):
          login_url = '/login/'
          redirect_field_name = 'redirect_to'

      有關(guān)其他詳細(xì)信息,請查看Django文檔。

      示例 - 列出當(dāng)前用戶的書本節(jié)

      現(xiàn)在我們知道,如何將頁面限制為特定用戶,讓我們?yōu)楫?dāng)前用戶借閱的書本,創(chuàng)建一個(gè)視圖。

      不幸的是,我們還沒有辦法讓用戶借書!因此,在我們創(chuàng)建圖書清單之前,我們首先會擴(kuò)展BookInstance模型,以支持借閱的概念,并使用Django Admin應(yīng)用程序,借給測試用戶一些書。

      模型節(jié)

      首先,我們必須讓用戶可以借用書本實(shí)例BookInstance(我們已經(jīng)擁有狀態(tài)status和還書日期due_back,但這個(gè)模型和用戶之間,沒有任何關(guān)聯(lián)。我們將使用ForeignKey(一對多)字段,來創(chuàng)建一個(gè)。我們還需要一個(gè)簡單的機(jī)制,來測試借出的書是否過期。

      打開 catalog/models.py,然后從 django.contrib.auth.models  導(dǎo)入 User模型(在文件頂部的上一個(gè)導(dǎo)入行的正下方添加它,好讓后續(xù)代碼可以使用 User):

      from django.contrib.auth.models import User

      接下來將借用者字段borrower,添加到BookInstance模型:

      borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)

      當(dāng)我們在這里,讓我們添加一個(gè)屬性,我們可以從模板中調(diào)用它,來判斷特定的書本實(shí)例是否過期。雖然我們可以在模板本身中計(jì)算這一點(diǎn),但使用如下所示的屬性會更有效率。將其添加到文件的底部:

      from datetime import date
      
      @property
      def is_overdue(self):
          if self.due_back and date.today() > self.due_back:
              return True
          return False

      注意: 在進(jìn)行比較之前,我們首先驗(yàn)證due_back是否為空??盏?code>due_back字段,會導(dǎo)致Django拋出錯(cuò)誤,而不是顯示頁面:空值不具有可比性。這不是我們希望用戶體驗(yàn)到的東西!

      現(xiàn)在我們已經(jīng)更新了模型,我們需要對項(xiàng)目進(jìn)行新的遷移,然后應(yīng)用這些遷移:

      python3 manage.py makemigrations
      python3 manage.py migrate

      管理員節(jié)

      現(xiàn)在打開 catalog/admin.py,并將borrower字段,添加到BookInstanceAdmin類別中的list_displayfieldsets,如下所示。這將使該字段在Admin部分中可見,以便我們可以在需要時(shí)將User分配給BookInstance

      @admin.register(BookInstance)
      class BookInstanceAdmin(admin.ModelAdmin):
          list_display = ('book', 'status', 'borrower', 'due_back', 'id')
          list_filter = ('status', 'due_back')
          
          fieldsets = (
              (None, {
                  'fields': ('book','imprint', 'id')
              }),
              ('Availability', {
                  'fields': ('status', 'due_back','borrower')
              }),
          )

      借幾本書節(jié)

      現(xiàn)在可以將書本借給特定用戶,然后借出一些BookInstance記錄。將他們的借用字段borrowed,設(shè)置為您的測試用戶,將狀態(tài)status設(shè)置為 “On loan”,并在將來和過去設(shè)置截止日期。

      注意: 我們不會一步一步說明這個(gè)流程,因?yàn)槟呀?jīng)知道如何使用管理站點(diǎn)!

      在借書視圖節(jié)

      現(xiàn)在我們將添加一個(gè)視圖,以獲取已經(jīng)借給當(dāng)前用戶的所有書本列表。我們將使用我們熟悉的、基于類的通用類列表視圖,但這次我們還將導(dǎo)入并派生自LoginRequiredMixin,以便只有登錄用戶才能調(diào)用此視圖。我們還將選擇聲明template_name,而不是使用默認(rèn)值,因?yàn)槲覀冏罱K可能會有幾個(gè)不同的 BookInstance 記錄列表,其中包含不同的視圖和模板。

      將以下內(nèi)容添加到 catalog/views.py:

      from django.contrib.auth.mixins import LoginRequiredMixin
      
      class LoanedBooksByUserListView(LoginRequiredMixin,generic.ListView):
          """
          Generic class-based view listing books on loan to current user. 
          """
          model = BookInstance
          template_name ='catalog/bookinstance_list_borrowed_user.html'
          paginate_by = 10
          
          def get_queryset(self):
              return BookInstance.objects.filter(borrower=self.request.user).filter(status__exact='o').order_by('due_back')

      為了將查詢,限制為當(dāng)前用戶的BookInstance對象,我們重新實(shí)現(xiàn)了get_queryset(),如上所示。請注意,“o”是表示借出當(dāng)中“on loan”的存儲代碼,我們按due_back日期排序,以便首先顯示最舊的項(xiàng)目。

      借書的 URL 設(shè)置節(jié)

      現(xiàn)在打開/catalog/urls.py,并添加指向上面視圖的path()(您只需將下面的文本復(fù)制到文件末尾)。

      urlpatterns += [   
          path('mybooks/', views.LoanedBooksByUserListView.as_view(), name='my-borrowed'),
      ]

      借書的模板節(jié)

      現(xiàn)在,我們需要為此頁面添加一個(gè)模板。首先,創(chuàng)建模板文件/catalog/templates/catalog/bookinstance_list_borrowed_user.html,并為其提供以下內(nèi)容:

      {% extends "base_generic.html" %}
      
      {% block content %}
          <h1>Borrowed books</h1>
      
          {% if bookinstance_list %}
          <ul>
      
            {% for bookinst in bookinstance_list %} 
            <li class="{% if bookinst.is_overdue %}text-danger{% endif %}">
              <a href="{% url 'book-detail' bookinst.book.pk %}">{{bookinst.book.title}}</a> ({{ bookinst.due_back }})        
            </li>
            {% endfor %}
          </ul>
      
          {% else %}
            <p>There are no books borrowed.</p>
          {% endif %}       
      {% endblock %}

      此模板與我們之前為 Book Author對象創(chuàng)建的模板非常相似。這里唯一新的東西,是我們檢查在模型中添加的方法(bookinst.is_overdue),并使用它,來更改過期項(xiàng)目的顏色。

      當(dāng)開發(fā)服務(wù)器運(yùn)行時(shí),您現(xiàn)在應(yīng)該能夠在瀏覽器中,查看登錄用戶的列表,網(wǎng)址為http://127.0.0.1:8000/catalog/mybooks/。在您的用戶登錄并登出后,嘗試此操作(在第二種情況下,您應(yīng)該被重定向到登錄頁面)。

       

      將列表添加到側(cè)欄節(jié)

      最后一步,是將這個(gè)新頁面的鏈接,添加到側(cè)邊欄中。我們將把它放在我們?yōu)榈卿浻脩麸@示其他信息的同一部分。

      打開基本模板(/locallibrary/catalog/templates/base_generic.html),并將粗體標(biāo)識的那一行,添加到側(cè)邊欄區(qū)塊,如下所示。

      <ul class="sidebar-nav">
         {% if user.is_authenticated %}
         <li>User: {{ user.get_username }}</li>
         <li><a href="{% url 'my-borrowed' %}">My Borrowed</a></li>
         <li><a href="{% url 'logout'%}?next={{request.path}}">Logout</a></li>   
         {% else %}
         <li><a href="{% url 'login'%}?next={{request.path}}">Login</a></li>   
         {% endif %} 
       </ul>

      它看起來是什么樣子的?節(jié)

      當(dāng)任何用戶登錄時(shí),他們會在側(cè)欄中看到 My Borrowed 鏈接,并顯示如下所示的書本列表(第一本書沒有截止日期,這是我們希望在以后的教程中修復(fù)的錯(cuò)誤!) 。

      Library - borrowed books by user

      權(quán)限節(jié)

      權(quán)限與模型相關(guān)聯(lián),并定義可以由具有權(quán)限的用戶,在模型實(shí)例上執(zhí)行的操作。默認(rèn)情況下,Django會自動(dòng)為所有模型提供添加,更改和刪除權(quán)限,這允許具有權(quán)限的用戶,通過管理站點(diǎn)執(zhí)行相關(guān)操作。您可以為模型定義自己的權(quán)限,并將其授予特定用戶。您還可以更改與同一模型的不同實(shí)例關(guān)聯(lián)的權(quán)限。

      對于視圖和模板中的權(quán)限測試,非常類似于對身份驗(yàn)證狀態(tài)的測試(實(shí)際上,測試權(quán)限也會測試身份驗(yàn)證)。

      模型節(jié)

      在模型“class Meta”部分上,使用 permissions字段,完成權(quán)限定義。您可以在元組中指定所需的權(quán)限,每個(gè)權(quán)限本身,都在包含權(quán)限名稱和權(quán)限顯示值的嵌套元組中被定義。例如,我們可能會定義一個(gè)權(quán)限,允許用戶標(biāo)記已歸還的圖書,如下所示:

      class BookInstance(models.Model):
          ...
          class Meta:
              ...
              permissions = (("can_mark_returned", "Set book as returned"),)  

      然后,我們可以將權(quán)限分配給管理站點(diǎn)中的圖書管理員“Librarian”分組。打開 catalog/models.py,然后添加權(quán)限,如上所示。您需要重新運(yùn)行遷移(調(diào)用 python3 manage.py makemigrationspython3 manage.py migrate),以適當(dāng)?shù)馗聰?shù)據(jù)庫。

       

      模板節(jié)

      當(dāng)前用戶的權(quán)限,存在名為 {{ perms }}的模板變量中。您可以使用關(guān)聯(lián)的Django “app” 中的特定變量名,來檢查當(dāng)前用戶是否具有特定權(quán)限 - 例如,如果用戶具有此權(quán)限,則 {{ perms.catalog.can_mark_returned }}將為True,否則為False。我們通常使用模板標(biāo)記 {% if %} 測試權(quán)限,如下所示:

      {% if perms.catalog.can_mark_returned %}
          <!-- We can mark a BookInstance as returned. -->
          <!-- Perhaps add code to link to a "book return" view here. -->
      {% endif %}
      

      視圖節(jié)

      在功能視圖中,可以使用 permission_required裝飾器,或在基于類別的視圖中,使用 PermissionRequiredMixin測試權(quán)限。模式和行為與登錄身份驗(yàn)證相同,但當(dāng)然您可能需要添加多個(gè)權(quán)限。

      功能視圖裝飾器:

      from django.contrib.auth.decorators import permission_required
      
      @permission_required('catalog.can_mark_returned')
      @permission_required('catalog.can_edit')
      def my_view(request):
          ...

      基于類別視圖的權(quán)限要求 mixin。

      from django.contrib.auth.mixins import PermissionRequiredMixin
      
      class MyView(PermissionRequiredMixin, View):
          permission_required = 'catalog.can_mark_returned'
          # Or multiple permissions
          permission_required = ('catalog.can_mark_returned', 'catalog.can_edit')
          # Note that 'catalog.can_edit' is just an example
          # the catalog application doesn't have such permission!

      示例節(jié)

      我們不會在這里更新 LocalLibrary;也許在下一個(gè)教程中!

      挑戰(zhàn)自己節(jié)

      在本文前面,我們向您展示了,如何為當(dāng)前用戶創(chuàng)建一個(gè)頁面,列出他們借用的書本。現(xiàn)在的挑戰(zhàn),是創(chuàng)建一個(gè)只對圖書館員可見的類似頁面,它顯示所有借用的書本,其中包括每個(gè)借用人的名字。

      您應(yīng)該能夠遵循與其他視圖相同的模式。主要區(qū)別在于,您需要將視圖限制為僅限圖書館員。您可以根據(jù)用戶是否是工作人員(函數(shù)裝飾器:staff_member_required,模板變量:user.is_staff)來執(zhí)行此操作,但我們建議您改為使用can_mark_returned權(quán)限,和 PermissionRequiredMixin,如上一節(jié)所述。

      重要: 請記住,不要使用超級用戶進(jìn)行基于權(quán)限的測試(即使尚未定義權(quán)限,權(quán)限檢查也會對超級用戶返回 true)。而是要?jiǎng)?chuàng)建一個(gè)圖書管理員用戶,并添加所需的功能。

      完成后,您的頁面應(yīng)該類似于下面的屏幕截圖。

      All borrowed books, restricted to librarian

      總結(jié)節(jié)

      做的太好了 — 你已經(jīng)創(chuàng)造了一個(gè)網(wǎng)站,圖書館用戶可以登入并檢視他們擁有的內(nèi)容,圖書管理員(有正確的授權(quán))可以檢視所有借出的書本以及借閱者。目前,我們?nèi)匀恢皇遣榭磧?nèi)容,但是當(dāng)您想要開始修改和添加數(shù)據(jù)時(shí),會使用相同的原則和技術(shù)。

      在我們的下一篇文章,我們將介紹如何使用Django 表單,收集使用者輸入,然后開始修改我們儲存的一些資料。

      也可以參考節(jié)

       

      本教程文檔節(jié)

       

        本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多