zoukankan      html  css  js  c++  java
  • 项目一: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'
    效果如下:

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



  • 相关阅读:
    多态
    重载 特点
    java 测量运行时间 单位:毫秒
    java 源代码 二分查找 Arrays
    java 同步 synchronized
    云服务器,价格其实不便宜,但为什么还要用呢
    网站访问优化(二):开启apache服务器gzip压缩
    CXF整合Spring开发WebService
    网站访问优化,未完待续
    网站访问优化,未完待续
  • 原文地址:https://www.cnblogs.com/eaglesour/p/8471271.html
Copyright © 2011-2022 走看看