django自定义用户认证(使用自定义的UserProfile,而不是django自带的),就需要(django要求)将为UserProfile单独创建一个app,这个app啥也不干,就是为UserProfile而生的;
这里我们创建一个app,名字叫做custom_auth,事实上,我们只需要对其中的models文件和admin.py做操作就可以了;
第一步:
创建user model
下面是models.py文件的内容:
1 from django.utils.safestring import mark_safe 2 from django.db import models 3 from django.contrib.auth.models import ( 4 BaseUserManager, AbstractBaseUser,PermissionsMixin 5 ) 6 7 class UserProFileManager(BaseUserManager): 8 def create_user(self, email, name, password=None): 9 """ 10 Creates and saves a User with the given email, name and password. 11 """ 12 if not email: 13 raise ValueError(‘Users must have an email address‘) 14 15 user = self.model( 16 email=self.normalize_email(email), 17 name=name, 18 ) 19 20 user.set_password(password) 21 user.save(using=self._db) 22 return user 23 24 def create_superuser(self, email, name, password): 25 """ 26 Creates and saves a superuser with the given email, name and password. 27 """ 28 user = self.create_user( 29 email, 30 password=password, 31 name=name, 32 ) 33 user.is_superuser = True 34 user.save(using=self._db) 35 return user 36 37 class UserProFile(AbstractBaseUser,PermissionsMixin): 38 email = models.EmailField( 39 verbose_name=‘email address‘, 40 max_length=255, 41 unique=True, 42 blank=True, 43 null=True 44 ) 45 password = models.CharField( 46 verbose_name=‘password‘, 47 max_length=128, 48 help_text=mark_safe("<a class=‘btn-link‘href=‘password‘>重置密码</a>"), 49 ) 50 name = models.CharField(max_length=32, verbose_name=‘姓名‘) 51 role = models.ManyToManyField(‘Role‘, null=True, blank=True) 52 is_active = models.BooleanField(default=True) 53 is_staff = models.BooleanField(default=True) 54 is_superuser = models.BooleanField(default=False) 55 56 objects = UserProFileManager() 57 58 USERNAME_FIELD = ‘email‘ 59 REQUIRED_FIELDS = [‘name‘] 60 61 def get_full_name(self): 62 # The user is identified by their email address 63 return self.email 64 65 def get_short_name(self): 66 # The user is identified by their email address 67 return self.email 68 69 def __str__(self): # __unicode__ on Python 2 70 return self.email 71 72 class Meta: 73 # verbose_name = ‘CRM账户‘ 74 verbose_name_plural = ‘CRM账户‘ 75 permissions = ( 76 (‘crm_table_list‘, ‘可以查看kingadmin所有表的数据‘), 77 (‘crm_table_list_view‘, ‘可以查看kingadmin所有表里数据的修改页‘), 78 (‘crm_table_list_change‘, ‘可以修改kingadmin所有表数据‘), 79 (‘crm_table_list_add_view‘, ‘可以查看kingadmin所有表添加页‘), 80 (‘crm_table_list_add‘, ‘可以在kingadmin所有表添加数据‘), 81 (‘crm_personal_password_reset_view‘, ‘可以在kingadmin查看自己的秘密修改页‘), 82 (‘crm_personal_password_reset‘, ‘可以在kingadmin修改自己的密码‘), 83 )
models表结构
在基类AbstractBaseUser中:
class Meta: abstract = True 只把传递给继承者,自身不创建表
对于类UaerproFile注意如下:
其中objects = UserProfileManager()是为了引用创建超级用户和普通用户所定义的方法,USERNAME_FIELD,REQUIRED_FIELDS按需进行修改; USERNAME_FIELD = ‘email‘ # 定义哪个字段是用户名字段,即对应登陆页面中的用户名 REQUIRED_FIELDS = [‘name‘] # 定义必填字段有哪些 即python3.6 manage.py createsuperuser调用的方法,这个类就定义了两个方法,create_user和create_superuser: 对于类UserProfileManager注意如下:
这里需要注意的是,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让数据表定义生效。
第二步:
to register this custom user model with Django’s admin, the following code would be required in the app’s admin.py
file
1 from crm import models 2 3 4 5 from django import forms 6 from django.contrib import admin 7 from django.contrib.auth.models import Group 8 from django.contrib.auth.admin import UserAdmin as BaseUserAdmin 9 from django.contrib.auth.forms import ReadOnlyPasswordHashField 10 11 from crm.models import UserProFile 12 13 14 class UserCreationForm(forms.ModelForm): 15 """A form for creating new users. Includes all the required 16 fields, plus a repeated password.""" 17 password1 = forms.CharField(label=‘Password‘, widget=forms.PasswordInput) 18 password2 = forms.CharField(label=‘Password confirmation‘, widget=forms.PasswordInput) 19 20 class Meta: 21 model = UserProFile 22 fields = (‘email‘, ‘name‘) 23 24 def clean_password2(self): 25 # Check that the two password entries match 26 password1 = self.cleaned_data.get("password1") 27 password2 = self.cleaned_data.get("password2") 28 if password1 and password2 and password1 != password2: 29 raise forms.ValidationError("Passwords don‘t match") 30 return password2 31 32 def save(self, commit=True): 33 # Save the provided password in hashed format 34 user = super().save(commit=False) 35 user.set_password(self.cleaned_data["password1"]) # 把明文 根据算法改成密文 36 if commit: 37 user.save() 38 return user 39 40 class UserChangeForm(forms.ModelForm): 41 """A form for updating users. Includes all the fields on 42 the user, but replaces the password field with admin‘s 43 password hash display field. 44 """ 45 password = ReadOnlyPasswordHashField() 46 47 class Meta: 48 model = UserProFile 49 fields = (‘email‘, ‘password‘, ‘name‘, ‘is_active‘, ‘is_superuser‘) 50 51 def clean_password(self): 52 # Regardless of what the user provides, return the initial value. 53 # This is done here, rather than on the field, because the 54 # field does not have access to the initial value 55 return self.initial["password"] 56 57 class UserProFileAdmin(BaseUserAdmin): 58 # The forms to add and change user instances 59 form = UserChangeForm 60 add_form = UserCreationForm 61 62 # The fields to be used in displaying the User model. 63 # These override the definitions on the base UserAdmin 64 # that reference specific fields on auth.User. 65 list_display = (‘email‘, ‘name‘, ‘is_superuser‘) 66 list_filter = (‘is_superuser‘,) 67 fieldsets = ( 68 (None, {‘fields‘: (‘email‘, ‘password‘)}), 69 (‘Personal info‘, {‘fields‘: (‘name‘,)}), 70 (‘Permissions‘, {‘fields‘: (‘is_active‘,‘is_staff‘,‘is_superuser‘,‘role‘,‘user_permissions‘,‘groups‘,)}), 71 ) 72 # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin 73 # overrides get_fieldsets to use this attribute when creating a user. 74 add_fieldsets = ( 75 (None, { 76 ‘classes‘: (‘wide‘,), 77 ‘fields‘: (‘email‘, ‘name‘, ‘password1‘, ‘password2‘)} 78 ), 79 ) 80 search_fields = (‘email‘,) 81 ordering = (‘email‘,) 82 filter_horizontal = (‘role‘,‘groups‘,‘user_permissions‘) 83 84 85 86 87 88 class CustomerAdmin(admin.ModelAdmin): 89 list_display = [‘name‘, ‘source‘, ‘contact_type‘, ‘contact‘, ‘consultant‘, ‘consult_content‘, ‘status‘, ‘date‘] 90 list_filter = [‘source‘, ‘consultant‘, ‘status‘, ‘date‘] 91 search_fields = [‘name‘,‘contact‘,‘source‘] 92 # readonly_fields = [‘contact‘,‘status‘] 93 filter_horizontal = [‘consult_courses‘] 94 actions = [‘change_status‘, ] 95 96 def change_status(self, request, querysets): 97 print(self, request, querysets) 98 querysets.update(status=0) 99 100 admin.site.register(models.CustomerInfo,CustomerAdmin) 101 admin.site.register(models.Menus) 102 admin.site.register(models.UserProFile,UserProFileAdmin) 103 admin.site.register(models.StudyRecord) 104 admin.site.register(models.CustomerFollowUp) 105 admin.site.register(models.Course) 106 admin.site.register(models.ClassList) 107 admin.site.register(models.CourseRecord) 108 admin.site.register(models.Branch) 109 admin.site.register(models.StudentEnrollment) 110 admin.site.register(models.ContractTemplate)
admin中自定义的form与注册代码
UserCreationForm # 创建新用户表单UserChangeForm # 改变用户信息表单
第三步:
需要在settings.py中指定用于用户认证的数据库表类
1 AUTH_USER_MODEL = ‘Wolf.UserProfile‘ #AppName.自定义user
最后,如果项目中已经存在其他的app,其他的app可能需要依赖UserProfile表,所以需要先将wolf注册,然后python manage.py makemigrations和python manage.py migrate同步之后,在将其他的app注册进来,创建其对应的表结构;
如果其他的表结果已经创建了,在运气非常不好的情况下,可能需要删除表才可以le~~~~~
原文地址:https://www.cnblogs.com/Lujun1028/p/9958025.html