AbstractUser 和AbstractBaseUser
- 自定义的局限性:自定义用户模型的安装会破坏所有从User拓展的代理模型
- 使用继承抽象User类定制user model, 会使得你在未来有需求时,更改user
- 可重用的app中不应该定义一个自定义user model
- Django希望你的用户模型要符合一些最低要求
- 如果你使用默认的验证后端, 那么模型必须具有一个unique字段(a single unique field), 用于鉴定目的.
AbstractBaseUser
AbstractBaseUser只提供核心的用户模型实现, 必须提供一些key实现细节:
- USERNAME_FIELD: 字符串, 用于指定字段作为唯一识别码(the unique identifier), 指定的字段必须配置
unique=True
, 除非使用自定义后端支持non-unique usernames
- EMAIL_FIELD (django1.11新增):
- REQUIRED_FIELDS: 列表, 提供使用createsuperuser时的字段, 必须提供所有的
blank=False
字段,
- is_active: boolean, 在AbstractBaseUser默认是True, 如何实现它取决于你依赖的auth后端.
- get_full_name(): 字符串, 用于标示用户
- get_short_name(): 字符串, 非正式的标识用户, 也可以返回和get_full_name()相同的值
AbstractBaseUser一般需要使用用户自定义的管理器, 其需要继承自BaseUserManager,并且要提供两个方法create_user和create_superuser:
create_user(*username_field*, password=None, **other_fields)
, username_field是用户模型中定义的USERNAME_FIELD, 必须提供,同时REQUIRED_FIELDS字段也要提供. 如使用email作为USERNAME_FIELD, date_of_birth是REQUIRED_FIELDS:
def create_user(self, email, date_of_birth, password=None):
# create user here
...
create_superuser(*username_field*, password, **other_fields)
, 其中也必须提供USERNAME_FIELD和REQUIRED_FIELDS的所有字段. 但是password是必须提供的. 以上例需求创建一个超级用户:
def create_superuser(self, email, date_of_birth, password):
...
AbstractBaseUser可以使用的属性和方法:
- get_username(): 返回USERNAME_FIELD指定字段的值
- clean(): 规范username, 通过调用narmalizi_username()
- classmethod get_email_field_name() [django1.11 新增]: 返回 EMAIL_FIELD指定的值, 如果没有指定默认是email
- classmethod normalize_username(username) [django1.11 新增]
- is_authenticated: 验证用户
- is_anonymous: 用于区分User和AnonymousUser
- set_password(raw_password):
- check_password(raw_password): 如果给的raw_password是对的, 返回True
- set_unusable_password(): 标记用户没有设置密码, check_password永远返回False
- has_usable_password(): set_unusable_password()被调用后,返回False
- get_session_auth_hash(): Returns an HMAC of the password field, 用于更改密码后的session失效
同时在管理器方面,需要自定义管理器
AbstractUser
AbstractUser是一个提供了对User全面的实现的抽象模型
如果你对Django的User模型很满意, 只是想添加一些配置信息(profile information), 你可以使用AbstractUser, 并且添加一些你的自定义字段.
继承自AbstractBaseUser和PermissionsMixin, 默认管理器是UserManager().
在字段方面,AbstractBaseUser额外提供了username, first_name, last_name, email, is_staff, date_joined. 并提供了AbstractBaseUser需要的字段
其USERNAME_FIELD = 'username'
,REQUIRED_FIELDS = ['email']
, 所以如果使用AbstractUser同时使用默认的UserManager()作为管理器, 需要提供username和email
注: 如果自定义用户模型定义了 username, email, is_staff, is_active, is_superuser, last_login, and date_joined字段,可以直接使用UserManager
BaseUserManager 提供的一些实用方法:
- classmethod normalize_email(email)
- get_by_natural_key(username):Retrieves a user instance using the contents of the field nominated by USERNAME_FIELD
- make_random_password(length=10, allowed_chars=‘abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789’), 用给出的长度length和给出的allowed_chars返回一个随机的密码, 注意allowed_chars没有包含 i, l, I, 1 和 o, O, 0
PermissionsMixin
继承抽象模型PermissionsMixin可以简单的应用Django 权限框架到你的用户模型中. 提供了所有支撑Django的权限模型的必要的方法和数据库字段
- is_superuser
- get_group_permissions(obj=None)
- get_all_permissions(obj=None)
- has_perm(perm, obj=None)
- has_perms(perm_list, obj=None)¶
- has_module_perms(package_name)
TIPS: 如果你没有包含 PermissionsMixin, 你必须确保你没有在ModelBackend启用权限模型. ModelBackend假定了你的用户模型有一些必要的字段.