iT邦幫忙

2023 iThome 鐵人賽

DAY 26
0

今天要來介紹 Django 的登入系統,登入系統的原理是用 session 機制,這邊就不特別介紹了,提供原文連結讓大家看:
https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Sessions

下面我們直接進行操作

登入系統模版

Django 有提供很方便的 註冊/登入 系統模版,而我們早在執行 django-admin startproject store 這個指令的時候,就已經幫我們順便建立好了,很方便吧!

我們現在來看一下登入系統程式碼有哪些:

# store/store/setting.py

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.
    # …
]

進到 store/store/setting.py 檔案後,會發現這兩段已經存在了,就是因為當初我們用指令快速產生的。

並且不知道你們還記不記得,當初我們在第一次下 python manage.py migrate 這個指令的時候,有很多的訊息產生,忘記得話可以回到 DAY4 觀看,不過我這邊也會再寫一次~

$ python3 manage.py migrate

------
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying sessions.0001_initial... OK

可以發現裡面幾乎都是 auth 開頭的訊息,這些訊息主要就是在幫你建立登入的 table 表單permissions 權限 一些設定

使用 admin 新增一個使用者

我們前面已經有一個超級使用者的帳號,但是今天如果你讓客戶使用該網站的話,不可能每一個都是超級使用者,一定是分有層級的,所以我們現在要新增一個無法進入 admin 後台的使用者。

而我們現在先使用 Django admin 後台來新增:

  1. 先進入 http://127.0.0.1:8000/admin/

  2. 輸入帳號密碼後進入後台

  3. 點擊新增 Groups
    https://ithelp.ithome.com.tw/upload/images/20231007/20162365X5gv8MozNX.png

  4. 寫上名字後,不用新增權限,直接按儲存
    https://ithelp.ithome.com.tw/upload/images/20231007/20162365d0vbzWkveB.png

  5. 點擊新增 Users
    https://ithelp.ithome.com.tw/upload/images/20231007/20162365gRByyiB2K1.png

  6. 輸入帳號密碼

https://ithelp.ithome.com.tw/upload/images/20231007/20162365WVTqSrz236.png

  1. 成功註冊後,會自動跳到個人資訊頁

  2. 補上個人資訊(姓名、信箱)、新增使用者的 Groups
    https://ithelp.ithome.com.tw/upload/images/20231007/201623653SesQwCQMg.png

  3. 最後儲存成功看到完成新增使用者

https://ithelp.ithome.com.tw/upload/images/20231007/201623655QURoSf2wc.png

新增使用者路徑 - urls.py

剛剛我們已經新增一個權限沒有這麼高的使用者了,我們現在把網站的登陸系統完成,首先當然是 路徑:

# store/store/urls.py

urlpatterns += [
    path('accounts/', include('django.contrib.auth.urls')),
]

Ps. 這邊的資料夾要注意喔,不是 store/online/urls.py,是 store/store/urls.py

這邊新增好後,我們到瀏覽器輸入這個連結 http://127.0.0.1:8000/accounts/,會看到以下畫面:

https://ithelp.ithome.com.tw/upload/images/20231007/20162365u0NMnkOSTy.png

可以發現雖然是一個錯誤的資訊,像是以下:

admin/
online/
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']

但是這些錯誤其實就是說,Django 已經幫你建置好這些路徑了:

http://127.0.0.1:8000/accounts/login/
http://127.0.0.1:8000/accounts/logout/
http://127.0.0.1:8000/accounts/password_change/
http://127.0.0.1:8000/accounts/password_change/done/
http://127.0.0.1:8000/accounts/password_reset/
http://127.0.0.1:8000/accounts/password_reset/done/
http://127.0.0.1:8000/accounts/reset/<uidb64>/<token>/
http://127.0.0.1:8000/accounts/reset/done/

所以我們現在連到此網址 http://localhost:8000/accounts/login ,但是他會顯示下面裡個錯誤,也就是說我們還沒建置好 templates 頁面,因此我們來補完。
https://ithelp.ithome.com.tw/upload/images/20231007/20162365E81Taagm0X.png

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

新增指定的 templates

依照上面的錯誤訊息,我們要新增一個 registration 資料夾和 login 檔案,這個 templates 資料夾,是跟 catalog 同層級喔,千萬要記得不要加在 online 資料夾 裡面的 templates 裡面:
https://ithelp.ithome.com.tw/upload/images/20231007/201623650OXhr12Y1s.png

<!-- store/templates/registration/login.html -->

123

不過你這樣新增完後,會發現畫面上還是說 templates 錯誤,這是為什麼呢?原因是因為下面在 settings 資料中,有設定以下程式關係:

# store/settings.py

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

預設情況下,系統會自動搜索 子類應用程式 中的 templates 資料夾,也就是 online 應用程式中的 templates 資料夾,那我們要怎麼改成讓 Django 搜索 根目錄的 templates 呢?

很間單,照下面這樣設定就可以:

# store/settings.py

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

這樣修改完後,我們再看一下瀏覽器的連結 http://127.0.0.1:8000/accounts/login/:
https://ithelp.ithome.com.tw/upload/images/20231007/20162365YTfr1FXsbe.png
可以發現這樣就成功印出 123

客製登入頁面

不過登入頁面不可能只有 123 字串,我們來補上登入頁面的詳細資訊:

  1. 一樣新增側邊欄
  2. 客製化 content 區塊
  3. 如果帳號密碼錯誤,跳出 form.errors 區塊
  4. 確認是否有 next 變數 - next變數 是什麼下面會解釋
  5. 確認 user 權限,如果 user 無權限,則跳出訊息
  6. 新增 form 表單
  7. 表單 method方法 要用 postaction 要用 login
  8. 設定 form 欄位,一個是 username,一個是 password 欄位
  9. 新增一個重置密的連結,我們後面會用到
<!-- online/templates/registration/login.html -->

{% extends "sidebar.html" %}

{% block content %}

  {% if form.errors %}
    <p>使用者的名稱和密碼錯誤,請再輸入一次</p>
  {% endif %}

  {% if next %}
    {% if user.is_authenticated %}      
      <p>您的帳戶無權訪問此頁面,要繼續,請使用有權訪問的帳戶登錄</p>
    {% else %}
      <p>請登錄</p>
    {% endif %}
  {% endif %}


  <form method="post" action="{% url 'login' %}">
    {% csrf_token %}
    <table>
      <tr>
        <td>{{ form.username.label_tag }}</td>
        <td>{{ form.username }}</td>
      </tr>
      <tr>
        <td>{{ form.password.label_tag }}</td>
        <td>{{ form.password }}</td>
      </tr>
    </table>
    <input type="submit" value="login">
    <input type="hidden" name="next" value="{{ next }}">
  </form>

  <!-- Assumes you setup the password_reset view in your URLconf -->
  <p><a href="{% url 'password_reset' %}">忘記密碼</a></p>

{% endblock %}

next 變數是啥
在 Django 中,next 是一個用於處理跳轉的變數。當用戶試圖訪問需要登入的頁面,但他們尚未登入時,Django 會將用戶重定向到登入頁面。
如果原始請求需要特定的頁面(即需要跳轉到某個特定頁面),Django 會將這個頁面的 URL 添加到 next 變數中。
ex. 假設你先到這個頁面 http://localhost:8000/online/employers,不過這個頁面需要登入的話,Django 會先幫你重定向到 login 頁面,此時就會把 http://localhost:8000/online/employers 存在 next 變數中,等到登入成功後,會自動導回該頁面。


如果聽不懂沒關係,後面會有實際案例~

這樣設定完之後,我們來看一下目前登入頁面的樣子,在瀏覽器輸入 http://127.0.0.1:8000/accounts/login/

https://ithelp.ithome.com.tw/upload/images/20231007/20162365AnvaFIQ65C.png

可以發現登入系統頁面已經有些樣子了,我們明天再繼續把登入系統完成~

總結

今天學到哪些東西呢?

  1. Django 登入系統介紹
  2. Django login 頁面資訊
  3. next 變數是什麼

最後附上 Github: https://github.com/eagle0526/Django-store


上一篇
DAY25 - Django admin 介紹 - 2
下一篇
DAY27 - Django 登入系統 - 2
系列文
Django 初學入門 - 從 ROR 的角度來學習 Django30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言