Django--自定义用户认证
Django自带的用户认证
以前都是用Django自带的用户认证,用户名字段一对一关系对应Django--User表(其实它也是继承了abstractbaseuser)。
| 1 2 3 | fromdjango.contrib.auth.models importUserclassUserInfo(models.Model):    username =models.OneToOneField(User) | 
为什么使用要自定义用户认证?
原生的Django--User认证只有用户名和密码字段,自定义用户认证可以根据项目的需求定制化和扩展认证系统。
比如把唯一标识改成email,或加入用户组等等。
官方说明
官方文档:
 
Specifying a custom User model(指定自定义用户模型)
使用Django自定义用户模型必须满足:
- 模型必须有一个唯一的字段,可用于识别目的。 
- 用户给定名称为“短”的标识,用户的全名为“长”标识符。他们可以返回完全相同的值。 
     构建一个符合用户自定义模型的最简单的方法是继承abstractbaseuser类。abstractbaseuser提供一个用户模型的核心实现,包括密码和符号密码重置。Django自带用用户认证User也是继承了它。一些关键的实现细节:
class models.CustomUser
USERNAME_FIELD
必须有一个唯一标识--USERNAME_FIELD
| 1 2 3 4 | classMyUser(AbstractBaseUser):    name =models.CharField(max_length=40, unique=True)    ...    USERNAME_FIELD ='name' | 
REQUIRED_FIELDS
创建superuser时的必须字段
| 1 2 3 4 5 6 | classMyUser(AbstractBaseUser):    ...    date_of_birth =models.DateField()    height =models.FloatField()    ...    REQUIRED_FIELDS =['date_of_birth', 'height'] | 
abstractbaseuser提供的方法
is_active(),is_authenticated()......
自定义models(略)
settings中添加models文件名
| 1 | AUTH_USER_MODEL ='app.MyUser(类名)'    | 
Django会去models中找这个类,所以要在原生的models.py中导入这个类。
代码实现
asset\user_models.py
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | #!/usr/bin/env python# -*- coding:utf-8 -*-fromdjango.db importmodelsfromdjango.contrib.auth.models import(    BaseUserManager, AbstractBaseUser)classUserProfileManager(BaseUserManager):    defcreate_user(self, email, name, password=None):        """        Creates and saves a User with the given email, name and password.        """        '''email是唯一标识,没有会报错'''        ifnotemail:            raiseValueError('Users must have an email address')        user =self.model(            email=self.normalize_email(email),            name=name,        )        user.set_password(password) #检测密码合理性        user.save(using=self._db)   #保存密码        returnuser    defcreate_superuser(self, email, name, password):        """        Creates and saves a superuser with the given email, name and password.        """        user =self.create_user(email,            password=password,            name=name        )        user.is_admin =True#比创建用户多的一个字段        user.save(using=self._db)        returnuserclassUserProfile(AbstractBaseUser):    email =models.EmailField(        verbose_name='email address',        max_length=255,        unique=True,    )    name =models.CharField(max_length=32)    is_active =models.BooleanField(default=True)    is_admin =models.BooleanField(default=False)    objects =UserProfileManager()    #创建用户    USERNAME_FIELD ='email'    REQUIRED_FIELDS =['name']    defget_full_name(self):        # The user is identified by their email address        returnself.email    defget_short_name(self):        # The user is identified by their email address        returnself.email    def__str__(self):              # __unicode__ on Python 2        returnself.email    '''django自带后台权限控制,对哪些表有查看权限等'''    defhas_perm(self, perm, obj=None):        "Does the user have a specific permission?"        # Simplest possible answer: Yes, always        returnTrue    '''用户是否有权限看到app'''    defhas_module_perms(self, app_label):        "Does the user have permissions to view the app `app_label`?"        # Simplest possible answer: Yes, always        returnTrue    @property    defis_staff(self):        "Is the user a member of staff?"        # Simplest possible answer: All admins are staff        returnself.is_admin | 
asset\models.py
| 1 | fromasset.user_models importUserProfile | 
myCMDB\settings.py
| 1 | AUTH_USER_MODEL ='asset.UserProfile' | 
asset\admin.py
| 1 2 | fromasset importmodelsadmin.site.register(models.UserProfile) | 
初始化数据库,登录后台。此时密码是明文显示,如果想改密码怎么办?
这时,需要自定义admin显示(官方都提供了)。
asset\admin.py
| 1 2 | fromuser_admin importUserAdminadmin.site.register(models.UserProfile,UserAdmin) | 
asset\user_admin.py
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | #!/usr/bin/env python# -*- coding:utf-8 -*-fromdjango importformsfromdjango.contrib importadminfromdjango.contrib.auth.models importGroupfromdjango.contrib.auth.admin importUserAdmin as BaseUserAdminfromdjango.contrib.auth.forms importReadOnlyPasswordHashFieldfromasset.models importUserProfileclassUserCreationForm(forms.ModelForm):    """A form for creating new users. Includes all the required    fields, plus a repeated password."""    password1 =forms.CharField(label='Password', widget=forms.PasswordInput)    password2 =forms.CharField(label='Password confirmation', widget=forms.PasswordInput)    classMeta:        model =UserProfile        fields =('email', 'name')    defclean_password2(self):        # Check that the two password entries match        password1 =self.cleaned_data.get("password1")        password2 =self.cleaned_data.get("password2")        ifpassword1 andpassword2 andpassword1 !=password2:            raiseforms.ValidationError("Passwords don't match")        returnpassword2    defsave(self, commit=True):        # Save the provided password in hashed format        user =super(UserCreationForm, self).save(commit=False)        user.set_password(self.cleaned_data["password1"])        ifcommit:            user.save()        returnuserclassUserChangeForm(forms.ModelForm):    """A form for updating users. Includes all the fields on    the user, but replaces the password field with admin's    password hash display field.    """    password =ReadOnlyPasswordHashField()    classMeta:        model =UserProfile        fields =('email', 'password', 'name', 'is_active', 'is_admin')    defclean_password(self):        # Regardless of what the user provides, return the initial value.        # This is done here, rather than on the field, because the        # field does not have access to the initial value        returnself.initial["password"]classUserAdmin(BaseUserAdmin):    # 以前是ModelAdmin    # The forms to add and change user instances    form =UserChangeForm    add_form =UserCreationForm    # The fields to be used in displaying the User model.    # These override the definitions on the base UserAdmin    # that reference specific fields on auth.User.    list_display =('email', 'name', 'is_admin')    #这个和以前一样,显示什么    list_filter =('is_admin',)    fieldsets =(        (None, {'fields': ('email', 'password')}),        ('Personal info', {'fields': ('name',)}),        ('Permissions', {'fields': ('is_admin',)}),    )    # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin    # overrides get_fieldsets to use this attribute when creating a user.    add_fieldsets =(        (None, {            'classes': ('wide',),            'fields': ('email', 'name', 'password1', 'password2')}        ),    )    search_fields =('email',)    ordering =('email',)    filter_horizontal =()# Now register the new UserAdmin...#admin.site.register(UserProfile, UserAdmin)# ... and, since we're not using Django's built-in permissions,# unregister the Group model from admin.admin.site.unregister(Group)    #不显示系统自带的group | 
后台效果
 
                     
                    
                 
                    
                




 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号