Django用户认证系统如何实现自定义


Posted in Python onNovember 12, 2020

自定义用户认证系统

Django 自带的用户认证系统已经可以满足大部分的情况,但是有时候我们需要某些特定的需求。Django 支持使用其他认证系统、也可以扩展Django的User模块,完全自定义新的认证模块。

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

a、拷贝以下代码到model文件中:

from django.db import models
from django.contrib.auth.models import (
  BaseUserManager, AbstractBaseUser
)
class MyUserManager(BaseUserManager):
  def create_user(self, email, name, password=None):
    """
    Creates and saves a User with the given email, date of
    birth and password.
    """
    if not email:
      raise ValueError('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)
    return user

  def create_superuser(self, email, name, password):
    """
    Creates and saves a superuser with the given email, date of
    birth and password.
    """
    user = self.create_user(
      email,
      password=password,
      name=name,
    )
    user.is_admin = True
    user.save(using=self._db)
    return user

class UserProfile(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 = MyUserManager()

  USERNAME_FIELD = 'email'
  REQUIRED_FIELDS = ['name']

  def __str__(self):
    return self.email

  def has_perm(self, perm, obj=None):
    "Does the user have a specific permission?"
    # Simplest possible answer: Yes, always
    return True

  def has_module_perms(self, app_label):
    "Does the user have permissions to view the app `app_label`?"
    # Simplest possible answer: Yes, always
    return True

  @property
  def is_staff(self):
    "Is the user a member of staff?"
    # Simplest possible answer: All admins are staff
    return self.is_admin

注意:email, name等字段都是可以自定义的

b、在admin.py中添加如下代码:

from django import forms
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField

from customauth.models import MyUser


class UserCreationForm(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)

  class Meta:
    model = MyUser
    fields = ('email', 'date_of_birth')

  def clean_password2(self):
    # Check that the two password entries match
    password1 = self.cleaned_data.get("password1")
    password2 = self.cleaned_data.get("password2")
    if password1 and password2 and password1 != password2:
      raise forms.ValidationError("Passwords don't match")
    return password2

  def save(self, commit=True):
    # Save the provided password in hashed format
    user = super().save(commit=False)
    user.set_password(self.cleaned_data["password1"])
    if commit:
      user.save()
    return user


class UserChangeForm(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()

  class Meta:
    model = MyUser
    fields = ('email', 'password', 'date_of_birth', 'is_active', 'is_admin')

  def clean_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
    return self.initial["password"]


class UserAdmin(BaseUserAdmin):
  # 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', 'date_of_birth', 'is_admin')
  list_filter = ('is_admin',)
  fieldsets = (
    (None, {'fields': ('email', 'password')}),
    ('Personal info', {'fields': ('date_of_birth',)}),
    ('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', 'date_of_birth', 'password1', 'password2')}
    ),
  )
  search_fields = ('email',)
  ordering = ('email',)
  filter_horizontal = ()

# Now register the new UserAdmin...
admin.site.register(MyUser, UserAdmin)
# ... and, since we're not using Django's built-in permissions,
# unregister the Group model from admin.
admin.site.unregister(Group)

C、 在settings.py中添加配置:

AUTH_USER_MODEL = 'customauth.MyUser' #customauth指APP name, MyUser指自定义的用户表model类
(这个时候仍然可以使用django.contrib.auth import authenticate,login,logout 等认证方法,只是保存数据的表不一样)

D、创建超级用户

首先我们要新建一个用户名,用来登陆管理网站,可以使用如下命令:

python manage.py createsuperuser

输入想要使用的用户名:

Username (leave blank to use 'administrator'): user01

输入email:

Email address: (在这里输入你的自己的邮箱帐号)

输入密码,需要输入两次,并且输入密码时不会显示出来:

Password:

Password (again):

当两次密码都相同的时候,就会提示超级帐号创建成功。

Superuser created successfully.

E、使用:

用前一步创建的用户,登陆后台管理系统http://0.0.0.0:8081/admin/

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python扫描IP段查看指定端口是否开放的方法
Jun 09 Python
在Django的视图中使用form对象的方法
Jul 18 Python
python简单商城购物车实例代码
Mar 15 Python
windows环境下tensorflow安装过程详解
Mar 30 Python
利用python的socket发送http(s)请求方法示例
May 07 Python
python中计算一个列表中连续相同的元素个数方法
Jun 29 Python
对pandas通过索引提取dataframe的行方法详解
Feb 01 Python
Python 3.8中实现functools.cached_property功能
May 29 Python
Python模块future用法原理详解
Jan 20 Python
django ORM之values和annotate使用详解
May 19 Python
keras模型保存为tensorflow的二进制模型方式
May 25 Python
Python万能模板案例之matplotlib绘制直方图的基本配置
Apr 13 Python
Django自带用户认证系统使用方法解析
Nov 12 #Python
Django多数据库联用实现方法解析
Nov 12 #Python
Django数据库迁移常见使用方法
Nov 12 #Python
python爬虫中PhantomJS加载页面的实例方法
Nov 12 #Python
python调用win32接口进行截图的示例
Nov 11 #Python
python 下载m3u8视频的示例代码
Nov 11 #Python
pytorch简介
Nov 11 #Python
You might like
mysql_fetch_assoc和mysql_fetch_row的功能加起来就是mysql_fetch_array
2007/01/15 PHP
提示Trying to clone an uncloneable object of class Imagic的解决
2011/10/27 PHP
PHP中使用xmlreader读取xml数据示例
2014/12/29 PHP
PHP设计模式之简单工厂和工厂模式实例分析
2019/03/25 PHP
jquery+json实现数据列表分页示例代码
2013/11/15 Javascript
javascript引用类型之时间Date和数组Array
2015/08/27 Javascript
如何解决手机浏览器页面点击不跳转浏览器双击放大网页
2016/07/01 Javascript
JS中的==运算: [''] == false —>true
2016/07/24 Javascript
AngularJS入门教程之表格实例详解
2016/07/27 Javascript
AngularJS实现DOM元素的显示与隐藏功能
2016/11/22 Javascript
Bootstrap栅格系统的使用详解
2017/10/30 Javascript
Vue中的Props(不可变状态)
2018/09/29 Javascript
基于JS实现父组件的请求服务过程解析
2019/10/14 Javascript
JS数组方法push()、pop()用法实例分析
2020/01/18 Javascript
vue中是怎样监听数组变化的
2020/10/24 Javascript
[46:48]DOTA2上海特级锦标赛A组小组赛#2 Secret VS CDEC第三局
2016/02/25 DOTA
在Python中操作时间之mktime()方法的使用教程
2015/05/22 Python
Django中URLconf和include()的协同工作方法
2015/07/20 Python
深入讲解Python编程中的字符串
2015/10/14 Python
Python随手笔记之标准类型内建函数
2015/12/02 Python
以视频爬取实例讲解Python爬虫神器Beautiful Soup用法
2016/01/20 Python
Python搭建APNS苹果推送通知推送服务的相关模块使用指南
2016/06/02 Python
Python利用pandas计算多个CSV文件数据值的实例
2018/04/19 Python
对Python中画图时候的线类型详解
2019/07/07 Python
Python 批量读取文件中指定字符的实现
2020/03/06 Python
python Yaml、Json、Dict之间的转化
2020/10/19 Python
详解CSS3中border-image的使用
2015/07/18 HTML / CSS
DOUGLAS波兰:在线销售香水和化妆品
2020/07/05 全球购物
运行时异常与一般异常有何异同?
2014/01/05 面试题
大学生如何写自荐信
2014/01/08 职场文书
2014年应届大学生毕业自我鉴定
2014/01/31 职场文书
退学证明范本3篇
2014/10/29 职场文书
员工旷工检讨书
2015/08/15 职场文书
2015年度学校应急管理工作总结
2015/10/22 职场文书
Java无向树分析 实现最小高度树
2022/04/09 Javascript
Golang解析JSON对象
2022/04/30 Golang