The easiest way to construct a compliant custom User model is to inherit fromAbstractBaseUser. AbstractBaseUser provides the core implementation of a Usermodel,including hashed passwords and tokenized password resets. You must then provide some key implementation details:
set_password(raw_password) 设置密码。按照给定的原始字符串设置用户的密码,taking care of the password hashing。 不保存 AbstractBaseUser 对象。如果没有给定密码,密码就会被设置成不使用,同用set_unusable_password()。
如果你完全满意Django的用户模型和你只是想添加一些额外的属性信息,你只需继承 django.contrib.auth.models.AbstractUser 然后添加自定义的属性。AbstractUser 作为一个抽象模型提供了默认的User的所有的实现(AbstractUser provides the full implementation of the default User as an abstract model.)。
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子类
<div class="line number3 index2 alt2"><code class="python spaces"><code class="python comments">A mixin class that adds the fields and methods necessary to support
<div class="line number4 index3 alt1"><code class="python spaces"><code class="python comments">Django's Group and Permission model using the ModelBackend.
<div class="line number7 index6 alt2"><code class="python spaces"><code class="python plain">helptext<code class="python keyword">=<code class="python plain">(<code class="python string">'Designates that this user has all permissions without '
<div class="line number10 index9 alt1"><code class="python spaces"><code class="python plain">blank<code class="python keyword">=<code class="python color1">True<code class="python plain">,helptext<code class="python keyword">=<code class="python plain">(<code class="python string">'The groups this user belongs to. A user will '
<div class="line number11 index10 alt2"><code class="python spaces"><code class="python string">'get all permissions granted to each of '
<div class="line number24 index23 alt1"><code class="python spaces"><code class="python comments">Returns a list of permission strings that this user has through their
<div class="line number25 index24 alt2"><code class="python spaces"><code class="python comments">groups. This method queries all available auth backends. If an object
<div class="line number26 index25 alt1"><code class="python spaces"><code class="python comments">is passed in,only permissions matching this object are returned.
<div class="line number39 index38 alt2"><code class="python spaces"><code class="python comments">Returns True if the user has the specified permission. This method
<div class="line number40 index39 alt1"><code class="python spaces"><code class="python comments">queries all available auth backends,but returns immediately if any
<div class="line number41 index40 alt2"><code class="python spaces"><code class="python comments">backend returns True. Thus,a user who has permission from a single
<div class="line number42 index41 alt1"><code class="python spaces"><code class="python comments">auth backend is assumed to have permission in general. If an object is
<div class="line number43 index42 alt2"><code class="python spaces"><code class="python comments">provided,permissions for this specific object are checked.
<div class="line number55 index54 alt2"><code class="python spaces"><code class="python comments">Returns True if the user has each of the specified permissions. If
<div class="line number56 index55 alt1"><code class="python spaces"><code class="python comments">object is passed,it checks if the user has all required perms for this
<div class="line number66 index65 alt1"><code class="python spaces"><code class="python comments">Returns True if the user has any permissions in the given app label.
<div class="line number67 index66 alt2"><code class="python spaces"><code class="python comments">Uses pretty much the same logic as has_perm,above.
def get_short_name(self):
</span><span style="color: #800000;">"</span><span style="color: #800000;">Returns the short name for the user.</span><span style="color: #800000;">"</span>
<span style="color: #0000ff;">return</span><span style="color: #000000;"> self.first_name
def email_user(self,subject,message,from_email</span>=None,**<span style="color: #000000;">kwargs):
</span><span style="color: #800000;">"""
Sends an email to <span style="color: #0000ff;">this<span style="color: #000000;"> User. <span style="color: #800000;">""" send_mail(subject,from_email,[self.email],**<span style="color: #000000;">kwargs)
<span style="color: #0000ff;">class<span style="color: #000000;"> User(AbstractUser): <span style="color: #800000;">""" Users within the Django authentication system are represented by <span style="color: #0000ff;">this<span style="color: #000000;">
model.
Username,password and email are required. Other fields are optional. <span style="color: #800000;">""" <span style="color: #0000ff;">class<span style="color: #000000;"> Meta(AbstractUser.Meta):
swappable = <span style="color: #800000;">'<span style="color: #800000;">AUTH_USER_MODEL<span style="color: #800000;">'
4.3.3 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 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.
5.官方提供的一个完整的例子
这是一个管理器允许的自定义user这个用户模型使用邮箱地址作为用户名,并且要求填写出生年月。it provides no permission checking,beyond a simple admin flag on the user account. This model would be compatible with all the built-in auth forms and views,except for the User creation forms. This example illustrates how most of the components work together,but is not intended to be copied directly into projects for production use.
<span style="color: #0000ff;">class<span style="color: #000000;"> MyUserManager(BaseUserManager):
def create_user(self,password=<span style="color: #000000;">None):
<span style="color: #800000;">"""
<span style="color: #000000;"> Creates and saves a User with the given email,date of
birth and password.
<span style="color: #800000;">"""
<span style="color: #0000ff;">if<span style="color: #000000;"> not email:
raise ValueError(<span style="color: #800000;">'<span style="color: #800000;">Users must have an email address<span style="color: #800000;">'<span style="color: #000000;">)
<span style="color: #000000;"> Creates and saves a superuser with the given email,date of
birth and password.
<span style="color: #800000;">"""
user =<span style="color: #000000;"> self.create_user(email,password=<span style="color: #000000;">password,date_of_birth=<span style="color: #000000;">date_of_birth
)
user.is_admin =<span style="color: #000000;"> True
user.save(<span style="color: #0000ff;">using=<span style="color: #000000;">self._db)
<span style="color: #0000ff;">return<span style="color: #000000;"> user
<span style="color: #0000ff;">class<span style="color: #000000;"> UserChangeForm(forms.ModelForm):
<span style="color: #800000;">"""<span style="color: #800000;">A form for updating users. Includes all the fields on
the user,but replaces the password field with admin<span style="color: #800000;">'<span style="color: #800000;">s
<span style="color: #000000;"> password hash display field.
<span style="color: #800000;">"""
password =<span style="color: #000000;"> ReadOnlyPasswordHashField()
</span><span style="color: #0000ff;">class</span><span style="color: #000000;"> Meta:
model </span>=<span style="color: #000000;"> MyUser
fields </span>= (<span style="color: #800000;">'</span><span style="color: #800000;">email</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">password</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">date_of_birth</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">is_active</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">is_admin</span><span style="color: #800000;">'</span><span style="color: #000000;">)
def clean_password(self):
# Regardless of what the user provides,</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> the initial value.
# This </span><span style="color: #0000ff;">is</span><span style="color: #000000;"> done here,rather than on the field,because the
# field does not have access to the initial value
</span><span style="color: #0000ff;">return</span> self.initial[<span style="color: #800000;">"</span><span style="color: #800000;">password</span><span style="color: #800000;">"</span><span style="color: #000000;">]