项目一:CRM(客户关系管理系统)--12--自定义用户认证

自定义的用户认证在django的官方网站中有详细的说明:

https://docs.djangoproject.com/en/2.0/topics/auth/customizing/

第一步:首先需要在models.py中需要定义两部分

1. 用于认证的数据表字段信息:

 1 class UserProfile(AbstractBaseUser):
 2     email = models.EmailField(
 3         verbose_name='邮箱地址',
 4         max_length=255,
 5         unique=True,
 6     )
 7     name = models.CharField(max_length=32, verbose_name='用户名称')
 8     date_of_birth = models.DateField(null=True, verbose_name='出生日期')
 9     is_active = models.BooleanField(default=True)
10     is_admin = models.BooleanField(default=False)
11 
12     objects = UserProfileManager()
13 
14     USERNAME_FIELD = 'email'  # 定义哪个字段是用户名字段,即对应登陆页面中的用户名
15     # REQUIRED_FIELDS = ['date_of_birth']
16     REQUIRED_FIELDS = ['name']  # 定义必填字段有哪些
17 
18     def __str__(self):
19         return self.email
20 
21     def has_perm(self, perm, obj=None):
22         "Does the user have a specific permission?"
23         # Simplest possible answer: Yes, always
24         return True
25 
26     def has_module_perms(self, app_label):
27         "Does the user have permissions to view the app `app_label`?"
28         # Simplest possible answer: Yes, always
29         return True
30 
31     @property
32     def is_staff(self):
33         "Is the user a member of staff?"
34         # Simplest possible answer: All admins are staff
35         return self.is_admin
36 
37     def get_short_name(self):
38         """
39 
40         :return:
41         """
42         pass
43 
44     class Meta:
45         verbose_name = verbose_name_plural = '登陆账户'
其中objects = UserProfileManager()是为了引用创建超级用户和普通用户所定义的方法,USERNAME_FIELD,REQUIRED_FIELDS按需进行修改;
USERNAME_FIELD = 'email'  # 定义哪个字段是用户名字段,即对应登陆页面中的用户名
REQUIRED_FIELDS = ['name']  # 定义必填字段有哪些
即python3.6 manage.py createsuperuser调用的方法,这个类就定义了两个方法,create_user和create_superuser:
 1 class UserProfileManager(BaseUserManager):
 2     def create_user(self, email, name, password=None):
 3         """
 4         Creates and saves a User with the given email, date of
 5         birth and password.
 6         """
 7         if not email:
 8             raise ValueError('Users must have an email address')
 9 
10         user = self.model(
11             email=self.normalize_email(email),
12             name=name,
13             # date_of_birth=date_of_birth,
14         )
15 
16         user.set_password(password)
17         user.is_active = True
18         user.save(using=self._db)
19         return user
20 
21     def create_superuser(self, email, name, password):
22         """
23         Creates and saves a superuser with the given email, date of
24         birth and password.
25         """
26         user = self.create_user(
27             email,
28             password=password,
29             # date_of_birth=date_of_birth,
30             name=name,
31         )
32         user.is_active = True
33         user.is_admin = True
34         user.save(using=self._db)
35         return user

这里需要注意的是,create_user/create_superuser需要与数据库对应的表定义的字段对应,参数传递也要一一对应;

用于认证的数据表需要定义一个get_short_name方法,否则会引发一个方法未重载的错误;原因就是UserProfile继承的基类

AbstractBaseUser强制重载该方法,如果没有该方法就引发一个异常:
def get_short_name(self):
raise NotImplementedError('subclasses of AbstractBaseUser must provide a get_short_name() method.')

数据表定义完后,需要python3.6 manage.py makemigrations/python3.6 manage.py migrate让数据表定义生效。

第二步:需要在admin.py中注册这两个类:UserProfile、UserProfileManager。

  1 from django.contrib import admin
  2 from django.shortcuts import render
  3 from . import models
  4 from django import forms
  5 from django.contrib import admin
  6 # from django.contrib.auth.models import Group
  7 from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
  8 from django.contrib.auth.forms import ReadOnlyPasswordHashField
  9 
 10 from CRM.models import UserProfile
 11 
 12 # Register your models here.
 13 
 14 
 15 class CustomerInfoAdmin(admin.ModelAdmin):
 16     list_display = ('qq', 'name', 'consultant', 'consult_course', 'status', 'date')
 17     list_filter = ('refer_path', 'consultant', 'date')
 18     search_fields = ('qq', 'name')
 19     raw_id_fields = ('consult_course', )
 20     list_editable = ('status', )
 21     filter_horizontal = ('tags', )
 22     actions = ("test_action",)
 23 
 24     def test_action(self, request, arg2):
 25         print('test action:', self, request, arg2)
 26         return render(request, "kingadmin/default.html")
 27     test_action.short_description = '测试'
 28 
 29 
 30 class UserCreationForm(forms.ModelForm):
 31     """A form for creating new users. Includes all the required
 32     fields, plus a repeated password."""
 33     password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
 34     password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
 35 
 36     class Meta:
 37         model = UserProfile
 38         fields = ('email', 'name', 'date_of_birth')
 39 
 40     def clean_password2(self):
 41         # Check that the two password entries match
 42         password1 = self.cleaned_data.get("password1")
 43         password2 = self.cleaned_data.get("password2")
 44         if password1 and password2 and password1 != password2:
 45             raise forms.ValidationError("Passwords don't match")
 46         return password2
 47 
 48     def save(self, commit=True):
 49         # Save the provided password in hashed format
 50         user = super().save(commit=False)
 51         user.set_password(self.cleaned_data["password1"])
 52         if commit:
 53             user.save()
 54         return user
 55 
 56 
 57 class UserChangeForm(forms.ModelForm):
 58     """A form for updating users. Includes all the fields on
 59     the user, but replaces the password field with admin's
 60     password hash display field.
 61     """
 62     password = ReadOnlyPasswordHashField()
 63 
 64     class Meta:
 65         model = UserProfile
 66         fields = ('email', 'password', 'name', 'date_of_birth', 'is_active', 'is_admin')
 67 
 68     def clean_password(self):
 69         # Regardless of what the user provides, return the initial value.
 70         # This is done here, rather than on the field, because the
 71         # field does not have access to the initial value
 72         return self.initial["password"]
 73 
 74 
 75 class UserProfileAdmin(BaseUserAdmin):
 76     # The forms to add and change user instances
 77     form = UserChangeForm
 78     add_form = UserCreationForm
 79 
 80     # The fields to be used in displaying the User model.
 81     # These override the definitions on the base UserAdmin
 82     # that reference specific fields on auth.User.
 83     list_display = ('email', 'name', 'date_of_birth', 'is_admin')
 84     list_filter = ('is_admin',)
 85     fieldsets = (
 86         (None, {'fields': ('email', 'name', 'password')}),
 87         ('Personal info', {'fields': ('date_of_birth',)}),
 88         ('Permissions', {'fields': ('is_admin',)}),
 89     )
 90     # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
 91     # overrides get_fieldsets to use this attribute when creating a user.
 92     add_fieldsets = (
 93         (None, {
 94             'classes': ('wide',),
 95             'fields': ('email', 'name', 'date_of_birth', 'password1', 'password2')}
 96         ),
 97     )
 98     search_fields = ('email',)
 99     ordering = ('email',)
100     filter_horizontal = ()
101 
102 # Now register the new UserAdmin...
103 admin.site.register(UserProfile, UserProfileAdmin)
104 admin.site.register(models.CustomerInfo, CustomerInfoAdmin)
105 admin.site.register(models.Campus)
106 admin.site.register(models.ClassRecord)
107 admin.site.register(models.ClassTable)
108 admin.site.register(models.Curriculum)
109 admin.site.register(models.CustomerFollowUp)
110 admin.site.register(models.Enrollment)
111 admin.site.register(models.LearningRecord)
112 admin.site.register(models.Menu)
113 admin.site.register(models.PaymentRecord)
114 admin.site.register(models.Role)
115 admin.site.register(models.Tag)
116 # admin.site.register(models.UserProfile)
117 # admin.site.register(models.UserProfileManager)
118 admin.site.register(models.SubMenu)
UserCreationForm  # 创建新用户表单
UserChangeForm    # 改变用户信息表单
第三步:需要在settings.py中指定用于用户认证的数据库表类:
AUTH_USER_MODEL = 'CRM.UserProfile'
效果如下:

自此,用户自定义认证基本完成,但是目前只能了解到这个程度,以后了解更多会在这里补充,也欢迎高人指点!!!



原文地址:https://www.cnblogs.com/eaglesour/p/8471271.html