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