django 用户设计

大多数时候,我们需要自己为自己的用户设计单独的数据表,而不是使用django本身的auth
那么我们需要继承AbstractBaseUser

Django 期望你自定义的 User model 满足一些最低要求

  1. 模型必须有一个唯一的字段可被用于识别目的。可以是一个用户名,电子邮件地址,或任何其它独特属性。
  2. 定制一个User Model最简单的方式是构造一个兼容的用户模型继承于AbstractBaseUser。
    AbstractBaseUser提供了User类最核心的实现,包括哈希的passwords和 标识的密码重置。

下面为一些AbstractBaseUser的子类必须定义的关键的字段和方法:

  1. USERNAME_FIELD
    必须设置。 设置认证标识,设置成标识的字段 unique=True
  2. 列表中不应该包含USERNAME_FIELD字段和password字段。
  3. is_active
    必须定义。 一个布尔属性,标识用户是否是 "active" 的。AbstractBaseUser默认为 Ture。
  4. get_full_name()
    必须定义。 long格式的用户标识。
  5. get_short_name()
    必须定义。 short格式的用户标识。

下面为一些AbstractBaseUser的子类可以使用的方法:

  1. get_username()
    返回 USERNAME_FIELD 的值。

  2. is_anonymous()
    一直返回 False。用来区分 AnonymousUser。

  3. is_authenticated()
    一直返回 Ture。用来告诉用户已被认证。

  4. set_password(raw_password)
    设置密码。按照给定的原始字符串设置用户的密码,taking care of the password hashing。 不保存 AbstractBaseUser 对象。如果没有给定密码,密码就会被设置成不使用,同用set_unusable_password()。

  5. check_password(raw_password)
    检查密码是否正确。 给定的密码正确返回 True。

  6. set_unusable_password()
    设置user无密码。 不同于密码为空,如果使用check_password(),则不会返回True。不保存AbstractBaseUser 对象。

  7. has_usable_password()
    如果设置了set_unusable_password(),返回False。

  8. 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没什么区别, 那么你还不如仅仅替换Django的UserManager就行了; 总之,如果你的User定义了不同的字段, 你就要去自定义一个管理器,它继承自BaseUserManager并提供两个额外的方法:

create_user(username_field, password=None, other_fields)
接受username field和required字段来创建用户。

create_superuser(username_field, password, other_fields)
接受username field和required字段来创建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 "." (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 ".". 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中手动创建的用户,其密码能够自动加密,那么重载你的user model的save方法

def save(self, *arg, **kwargs):
    self.password = func(self.password)
    super(User, self).save(*arg, **kwargs)

你可能感兴趣的:(django 用户设计)