大多數時候垦江,我們需要自己為自己的用戶設計單獨的數據表剩拢,而不是使用django本身的auth
那么我們需要繼承AbstractBaseUser
Django 期望你自定義的 User model 滿足一些最低要求
- 模型必須有一個唯一的字段可被用于識別目的臀玄∪〗伲可以是一個用戶名栋猖,電子郵件地址害碾,或任何其它獨特屬性。
- 定制一個User Model最簡單的方式是構造一個兼容的用戶模型繼承于AbstractBaseUser啊胶。
AbstractBaseUser提供了User類最核心的實現甸各,包括哈希的passwords和 標識的密碼重置。
下面為一些AbstractBaseUser的子類必須定義的關鍵的字段和方法:
- USERNAME_FIELD
必須設置焰坪。 設置認證標識趣倾,設置成標識的字段 unique=True - 列表中不應該包含USERNAME_FIELD字段和password字段。
- is_active
必須定義某饰。 一個布爾屬性儒恋,標識用戶是否是 "active" 的。AbstractBaseUser默認為 Ture黔漂。 - get_full_name()
必須定義诫尽。 long格式的用戶標識弥搞。 - get_short_name()
必須定義谨娜。 short格式的用戶標識。
下面為一些AbstractBaseUser的子類可以使用的方法:
get_username()
返回 USERNAME_FIELD 的值埋同。is_anonymous()
一直返回 False劳较。用來區(qū)分 AnonymousUser驹止。is_authenticated()
一直返回 Ture浩聋。用來告訴用戶已被認證。set_password(raw_password)
設置密碼臊恋。按照給定的原始字符串設置用戶的密碼衣洁,taking care of the password hashing。 不保存 AbstractBaseUser 對象抖仅。如果沒有給定密碼坊夫,密碼就會被設置成不使用,同用set_unusable_password()撤卢。check_password(raw_password)
檢查密碼是否正確环凿。 給定的密碼正確返回 True。set_unusable_password()
設置user無密碼放吩。 不同于密碼為空智听,如果使用check_password(),則不會返回True渡紫。不保存AbstractBaseUser 對象到推。has_usable_password()
如果設置了set_unusable_password(),返回False惕澎。get_session_auth_hash()
返回密碼字段的HMAC莉测。 Used for Session invalidation on password change.
為你的User模型自定義一個管理器
如果你的User模型定義了這些字段:username, email, is_staff, is_active, is_superuser, last_login, and date_joined跟默認的User沒什么區(qū)別, 那么你還不如僅僅替換Django的UserManager就行了; 總之,如果你的User定義了不同的字段, 你就要去自定義一個管理器,它繼承自BaseUserManager并提供兩個額外的方法:
create_user(username_field, password=None, other_fields)
接受username field和required字段來創(chuàng)建用戶唧喉。
create_superuser(username_field, password, other_fields)
接受username field和required字段來創(chuàng)建superuser捣卤。
擴展Django默認的User
如果你完全滿意Django的用戶模型和你只是想添加一些額外的屬性信息,你只需繼承 django.contrib.auth.models.AbstractUser 然后添加自定義的屬性。AbstractUser 作為一個抽象模型提供了默認的User的所有的實現(AbstractUser provides the full implementation of the default User as an abstract model.)八孝。
自定義用戶與內置身份驗證表單
Django內置的forms和views和相關聯的user model有一些先決條件董朝。如果你的user model沒有遵循同樣的條件,則需要定義一個替代的form唆阿,通過form成為身份驗證views配置的一部分益涧。
UserCreationForm
依賴于User Model. 擴展User時必須重寫。
UserChangeForm
依賴于User Model. 擴展User時必須重寫驯鳖。
AuthenticationForm
Works with any subclass of AbstractBaseUser, and will adapt to use the field defined in USERNAME_FIELD.
PasswordResetForm
Assumes that the user model has a field named email that can be used to identify the user and a boolean field named is_active to prevent password resets for inactive users.
SetPasswordForm
Works with 任何AbstractBaseUser子類
PasswordChangeForm
Works with 任何AbstractBaseUser子類
AdminPasswordChangeForm
Works with 任何AbstractBaseUser子類
自定義用戶和django.contrib.admin
如果你想讓你自定義的User模型也可以在站點管理上工作,那么你的模型應該再定義一些額外的屬性和方法久免。 這些方法允許管理員去控制User到管理內容的訪問:
is_staff
是否允許user訪問admin界面
is_active
用戶是否活躍浅辙。
has_perm(perm, obj=None):
user是否擁有perm權限。
has_module_perms(app_label):
user是否擁有app中訪問models的權限
你同樣也需要注冊你自定義的用戶模型到admin阎姥。如果你的自定義用戶模型擴展于django.contrib.auth.models.AbscustomauthtractUser记舆,你可以用django的 django.contrib.auth.admin.UserAdmin 類。如果你的用戶模型擴展于 AbstractBaseUser呼巴,你需要自定義一個ModelAdmin類泽腮。他可能繼承于默認的django.contrib.auth.admin.UserAdmin御蒲。然而,你也需要覆寫一些django.contrib.auth.models.AbstractUser 字段的定義不在你自定義用戶模型中的诊赊。
自定義用戶和權限
如果想讓在自定義用戶模型中包含Django的權限控制框架變得簡單厚满,Django提供了PermissionsMixin。這是一個抽象的類碧磅,你可以為你的自定義用戶模型中的類的層次結構中包含它碘箍。它提供給你所有Django權限類所必須的的方法和字段
PermissionsMixin提供的這些方法和屬性
is_superuser
布爾類型。 Designates that this user has all permissions without explicitly assigning them.
get_group_permissions(obj=None)
Returns a set of permission strings that the user has, through their groups.
If obj is passed in, only returns the group permissions for this specific object.
get_all_permissions(obj=None)
Returns a set of permission strings that the user has, both through group and user permissions.
If obj is passed in, only returns the permissions for this specific object.
has_perm(perm, obj=None)
Returns True if the user has the specified permission, where perm is in the format "<app label>.<permission codename>" (see permissions). If the user is inactive, this method will always return False.
If obj is passed in, this method won’t check for a permission for the model, but for this specific object.
has_perms(perm_list, obj=None)
Returns True if the user has each of the specified permissions, where each perm is in the format "<app label>.<permission codename>". If the user is inactive, this method will always return False.
If obj is passed in, this method won’t check for permissions for the model, but for the specific object.
has_module_perms(package_name)
Returns True if the user has any permissions in the given package (the Django app label). If the user is inactive, this method will always return False.
最后鲸郊,為了保證在admin或者xadmin中手動創(chuàng)建的用戶丰榴,其密碼能夠自動加密,那么重載你的user model的save方法
def save(self, *arg, **kwargs):
self.password = func(self.password)
super(User, self).save(*arg, **kwargs)