django用戶認證系統——拓展 User 模型


Django 用戶認證系統提供了一個內置的 User 對象,用於記錄用戶的用戶名,密碼等個人信息。對於 Django 內置的 User 模型, 僅包含以下一些主要的屬性:

  • username,即用戶名
  • password,密碼
  • email,郵箱
  • first_name,名
  • last_name,姓

對於一些網站來說,用戶可能還包含有昵稱、頭像、個性簽名等等其它屬性,因此僅僅使用 Django 內置的 User 模型是不夠。好在 Django 用戶系統遵循可拓展的設計原則,我們可以方便地拓展 User 模型。

繼承 AbstractUser 拓展用戶模型

這是推薦做法。事實上,查看 User 模型的源碼就知道,User 也是繼承自 AbstractUser 抽象基類,而且僅僅就是繼承了 AbstractUser,沒有對 AbstractUser 做任何的拓展。以下就是 User 的源碼:

class User(AbstractUser): """  Users within the Django authentication system are represented by this  model.  Username, password and email are required. Other fields are optional.  """ class Meta(AbstractUser.Meta): swappable = 'AUTH_USER_MODEL' 

所以,如果我們繼承 AbstractUser,將獲得 User 的全部特性,而且還可以根據自己的需求進行拓展。

我們之前新建了一個 users 應用,通常我們把和數據庫模型相關的代碼寫在 models.py 文件里。打開 users/models.py 文件,寫上我們自定義的用戶模型代碼:

users/models.py from django.db import models from django.contrib.auth.models import AbstractUser class User(AbstractUser): nickname = models.CharField(max_length=50, blank=True) class Meta(AbstractUser.Meta): pass 

我們給自定義的用戶模型新增了一個 nickname(昵稱)屬性,用來記錄用戶的昵稱信息,設置 blank=True 的目的是讓用戶在注冊時無需填寫昵稱。根據你的需求可以自己進一步拓展,例如增加用戶頭像、個性簽名等等,添加多少屬性字段沒有任何限制。

同時,我們繼承了 AbstractUser 的內部類屬性 Meta ,不過目前什么也沒做。在這里繼承 Meta 的原因是在你的項目中可能需要設置一些 Meta 類的屬性值,不要忘記繼承 AbstractUser.Meta 中已有的屬性。

注意:一定要繼承 AbstractUser,而不是繼承 auth.User。盡管 auth.User 繼承自 AbstractUser 且並沒有對其進行任何額外拓展,但 AbstractUser 是一個抽象類,而 auth.User 不是。如果你繼承了 auth.User 類,這會變成多表繼承,在目前的情況下這種繼承方式是不被推薦的。關於 Django 的抽象模型類和多表繼承,請查閱 Django 的官方文檔 模型繼承

此外,AbstractUser 類又繼承自 AbstractBaseUser,前者在后者的基礎上拓展了一套用戶權限(Permission)系統。因此如非特殊需要,盡量不要從 AbstractBaseUser 拓展,否則你需要做更多的額外工作。

為了讓 Django 用戶認證系統使用我們自定義的用戶模型,必須在 settings.py 里通過 AUTH_USER_MODEL 指定自定義用戶模型所在的位置,即需要如下設置:

django_auth_example/settings.py # 其它設置... AUTH_USER_MODEL = 'users.User' 

即告訴 Django,使用 users 應用下的 User 用戶模型。

順便再修改一下語言設置和時區設置:

django_auth_example/settings.py # 其它設置... LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai' 

設置好自定義用戶模型后,生成數據庫遷移文件,並且遷移數據庫以生成各個應用必要的數據庫表。即運行如下兩條命令:

$ python manage.py makemigrations
$ python manage.py migrate

OK,現在 Django 用戶系統使用的用戶模型就是自定義的 User 模型了。

注意:一定要在設置好 AUTH_USER_MODEL = 'users.User' 后在第一次遷移數據庫,即指定好自定義的用戶模型后再執行數據庫遷移命令。

使用 Profile 模式拓展用戶模型

如果想為一個已使用了 Django 內置 User 模型的項目拓展用戶模型,上述繼承 AbstractUser 的拓展方式會變得有點麻煩。Django 沒有提供一套自動化的方式將內置的 User 遷移到自定義的用戶模型,因為 Django 已經為內置的 User 模型生成了相關數據庫遷移文件和數據庫表。如果非要這么做的話,需要手工修改遷移文件和數據庫表,並且移動數據庫中相關的用戶數據。

所以我們采用另一種不改動數據庫表的方式來拓展用戶模型,具體來說,我們在創建一個模型(通常命名為 Profile)來記錄用戶相關的數據,然后使用一對一的方式將這個 Profile 模型和 User 關聯起來,就好像每個用戶都關聯着一張記錄個人資料的表一樣。代碼如下:

models.py from django.contrib.auth.models import User class Profile(models.Model): nickname = models.CharField(max_length=50, blank=True) user = models.OneToOneField(User) 

這種方式和 AbstractUser 的區別是,繼承 AbstractUser 的用戶模型只有一張數據庫表。而 Profile 這種模式有兩張表,一張是 User 模型對應的表,一張是 Profile 模型對應的表,兩張表通過一對一的關系關聯。可見,當要查詢某個用戶的 Profile 時,需要執行額外的跨表查詢操作,所以這種方式比起直接繼承 AbstractUser 效率更低一點。因此對於新項目來說,優先推薦使用繼承 AbstractUser 的方式來拓展用戶模型。

PS:如果你使用了Profile 模式,你可能希望在創建 User 對象的時候同時也創建與之關聯的 Profile 對象。你可以使用 Django 的 Signal 實現這個需求。由於 Profile 模式不是我們要介紹的重點內容,因此具體的實現細節請參照相關的文檔,這里不再贅述。

OK,自定義的 User 模型已經建立好了,接下來就是如何創建用戶,即用戶注冊流程了。

轉自:https://www.cnblogs.com/AmilyWilly/p/8469851.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM