西游之路——python全栈——自定义用户认证

  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

时间: 2024-10-08 13:08:20

西游之路——python全栈——自定义用户认证的相关文章

西游之路——python全栈——Django~1

知识预览 Django基本命令 二 路由配置系统(URLconf) 三 编写视图 四 Template 五 数据库与ORM admin的配置 一 什么是web框架? 框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单地说,就是你用别人搭建好的舞台来做表演. 对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端.   最简单的Web应用就是先把HTML用文件保存好,用一个现

西游之路——python全栈——通用模块(pager、check_code、form验证)

1.验证码 1 import random 2 from PIL import Image, ImageDraw, ImageFont, ImageFilter 3 4 _letter_cases = "abcdefghjkmnpqrstuvwxy" # 小写字母,去除可能干扰的i,l,o,z 5 _upper_cases = _letter_cases.upper() # 大写字母 6 _numbers = ''.join(map(str, range(3, 10))) # 数字 7

西游之路——python全栈——django中models配置

目录 Django支持多种数据库,sqlite,mysql,oracle等,其默认数据库是sqlite 在settings文件中可以发现: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } 其默认数据库是sqlite3 要想使用其他数据库,需要修改相应的引擎和配置 (1)sqlite: 'ENGINE': 'dja

西游之路——python全栈——Form组件字段及动态绑定

一.HTML中 | safe  可在后台用以下方式处理 1 text = "<input type'text' />" 2 from django.utils.safestring import mark_safe 3 text = mark_safe(text) 二.views.py操作 1 from django.shortcuts import render 2 3 from django import forms 4 from django.forms import

西游之路——python全栈——瀑布流

############################### class Picture(models.Model): src = models.ImageField(verbose_name='图片路径', upload_to='./static/images/picture/') title = models.CharField(verbose_name='标题', max_length=32) summary = models.CharField(verbose_name='简介', m

西游之路——python全栈——报障系统之后台管理

一.后台管理页面布局 1.用户: - 普通用户 知识库+提交报账单+个人信息 - 管理员 知识库+提交报账单+个人信息+处理报账单 - 超级管理员 知识库+提交报账单+个人信息+处理报账单+报障统计信息 权限管理2.菜单: - 知识库管理 文章 标签 分类 - 报障管理 个人报障 报障处理 报障统计信息 - 权限管理 菜单 权限 角色 二.公共模板及路由分发 1.后台菜单栏.导航栏 1 <!DOCTYPE html> 2 <html lang="en"> 3 &

西游之路——python全栈——ORM之SQLAlchemy(1)

目录 定义一个类,ORM(对象关系映射)将这个类转换为sql语句,使用pymysql进行执行 一,底层处理 使用engine/connectionpooling/dialect进行数据库操作,engine使用connectionpooling连接数据库,然后在通过dialect执行sql语句(SQLAlchemy本身无法操作数据库,其必须以来pymsql等第三方插件,Dialect用于和数据API进行交流,根据配置文件的不同调用不同的数据库API) pymysql mysql+pymysql:/

西游之路——python全栈——ORM之SQLAlchemy(3)外键与relationship的关系

目录 relationship是为了简化联合查询join等,创建的两个表之间的虚拟关系,这种关系与标的结构时无关的.他与外键十分相似,确实,他必须在外键的基础上才允许使用 不然会报错: sqlalchemy.exc.NoForeignKeysError: Could not determine join condition between parent/child tables on relationship Father.son - there are no foreign keys link

Python全栈之路_01

Python全栈之路 前言:因为Python主要是在Linux和widows操作系统上使用所以,首先就介绍Pyhton在这两个平台上的安装和一些基础知识 Linux系统下安装Pyhton 1.工具 虚拟机:VMware workstation 12 Pro Linux系统:CentOS 64 位 VMware虚拟机安装很简单就不说明了. 在虚拟机安装CentOS 需要注意的是: 运行内存分配1G左右即可 可以开机按F2进入bios界面boot目录下选择启动设备选择Hard Drive为优先启动位