Django基础之扩展内置用户模型

一:内置验证系统

1.1 auth模块

from django.contrib import auth

django.contrib.auth中提供了许多方法,这里主要介绍其中的三个

authenticate() :
提供了用户认证,即验证用户名以及密码是否正确,一般需要username password两个关键字参数
如果认证信息有效,会返回一个 User 对象。authenticate()会在User 对象上设置一个属性标识那种认证后端认证了该用户,且该信息在后面的登录过程中是需要的。当我们试图登陆一个从数据库中直接取出来不经过authenticate()的User对象会报错的!

user = authenticate(username='someone',password='somepassword')

注意:
在Django1.8版本中,authenticate方法传入username, password两个参数后是不校验is_active字段的
在Django2.0版本中,authenticate方法传入username, password两个参数后,如果is_active字段为False时,将返回None
如果想在Django2.0版本中校验 is_active 字段,可以settings配置文件中添加下面一行配置

AUTHENTICATION_BACKENDS = ['django.contrib.auth.backends.AllowAllUsersModelBackend']

login(HttpRequest, user):
该函数接受一个HttpRequest对象,以及一个认证了的User对象
此函数使用django的session框架给某个已认证的用户附加上session id等信息。

logout(request) 注销用户:
该函数接受一个HttpRequest对象,无返回值。当调用该函数时,当前请求的session信息会全部清除。该用户即使没有登录,使用该函数也不会报错。

1.2 User对象

如果是真正的 User 对象,返回值恒为 True 。 用于检查用户是否已经通过了认证。
通过认证并不意味着用户拥有任何权限,甚至也不检查该用户是否处于激活状态,这只是表明用户成功的通过了认证。 这个方法很重要, 在后台用request.user.is_authenticated判断用户是否已经登录,如果true则可以向前台展示request.user.username

login_required装饰器:
若用户没有登录,则会跳转到django默认的 登录URL '/accounts/login/ ’ (这个值可以在settings文件中通过LOGIN_URL进行修改)。并传递当前访问url的绝对路径 (登陆成功后,会重定向到该路径)。

create_user :
使用 create_user 辅助函数创建用户

from django.contrib.auth.models import User
def index(request):
    user = User.objects.create_user(username = 'andy', email = '[email protected]', password = '123456')
    # 在默认的auth_user表中创建用户,默认is_active = 1,激活的
    return HttpResponse('index page')

create_superuser:
创建后台超级用户

user = User.objects.create_superuser(username = 'rambo', email = '[email protected]', password = '123456')
# 当然也可以在命令行中创建

check_password:
用户需要修改密码的时候 首先要让他输入原来的密码 ,如果给定的字符串通过了密码检查,返回 True

set_password:
使用 set_password() 来修改密码

user = User.objects.get(username='')
user.set_password(password='')
user.save

1.3 用户认证实例

from django.shortcuts import render, redirect
from django.contrib import auth
from django.contrib.auth.decorators import login_required

@login_required
def index(request):
    return render(request, 'index.html')

def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        user = auth.authenticate(username = username, password = password)
        if user:
            auth.login(request, user)
            # path = request.GET.get('next', '/user/index/')
            path = request.GET.get('next') or '/user/index/'
            return redirect(path)
        else:
            return redirect('/user/login/')
    return render(request, 'login.html')

def logout(request):
    auth.logout(request)
    return redirect('/user/login/')

二:扩展内置用户模型

2.1 Proxy模型扩展

如果只需要在原有的基础之上增加一些操作方法的话,使用该方法

class Person(User):
    class Meta:
        proxy = True
    @classmethod
    def get_blacklist(cls):
        '''获取is_active=False的用户'''
        return cls.objects.filter(is_active=False)

注意:
只能添加方法,不能添加属性(也就是不能添加自定义字段)
操作Person类实际上就是操作User类

2.2 一对一外键扩展

如果想要在原来模型的基础之上添加新的字段,那么可以使用一对一外键的方式

from django.dispatch import receiver
from django.db.models.signals import post_save
class UserExtension(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='extension')
    telephone = models.CharField(max_length=11)
    school = models.CharField(max_length=100)
@receiver(post_save, sender = User)
def handler_user_extension(sender, instance, created, **kwargs):
    if created:
        UserExtension.objects.create(user = instance)
    else:
        instance.extension.save()

使用该方式可以自定义验证系统

2.3 继承AbstractUser扩展

from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
from django.db import models

class UserManager(BaseUserManager):

    def _create_user(self, mobile, username, password, **kwargs):
        if not all([mobile, username, password]):
            raise ValueError('mobile, username, password all required')
        user = self.model(mobile = mobile, username = username, **kwargs)
        user.set_password(password)
        user.save()
        return user

    def create_user(self, mobile, username, password, **kwargs):
        kwargs['is_superuser'] = False
        return self._create_user(mobile, username, password, **kwargs)

    def create_superuser(self, mobile, username, password, **kwargs):
        kwargs['is_superuser'] = True
        kwargs['is_staff'] = True
        return self._create_user(mobile, username, password, **kwargs)

class User(AbstractUser):
    telephone = models.CharField(max_length = 11, unique = True)
    school = models.CharField(max_length = 100)
    USERNAME_FIELD = 'telephone' # 告诉Django,在使用authenticate()方法做验证时使用telephone这个字段,user=authenticate(request,username=telephone,password=password)
    objects = UserManager()
    class Meta:
        db_table = 'user'

Django默认的验证系统 authenticate() 方法需要传递 username, password二个字段,通过上面的UserManager方法对create_user方法,使用其支持传递自定义的三个字段:telephone, username, password
在调用 authenticate验证方法时默认传递的参数是 username = username, password = password,经过上面 USERNAME_FIELD = ‘telephone’,在传递参数时需要传递 username = telephone, password = password
创建完数据模型后,还必须通知django,要使用自定义的User模型类。在settings配置文件中添加下面一行代码:

AUTH_USER_MODEL = 'user.User'   # APP_name.模型

2.4 继承AbstractBaseUser

如果想改变默认的验证方式,并且对于原User模型上的一些字段不想要,那么可以自定义一个模型,然后继承自AbstractBaseUser,再次添加你想要的字段。这种方式比较麻烦,最好是确定自己对Django比较了解才使用。

from django.contrib.auth.base_user import BaseUserManager, AbstractBaseUser
from django.contrib.auth.models import AbstractUser, PermissionsMixin
class User(AbstractBaseUser, PermissionsMixin):
    username = models.CharField(max_length = 50)
    email = models.EmailField(unique = True)
    telephone = models.CharField(max_length=11, unique = True)
    is_active = models.BooleanField(default = True)

    USERNAME_FIELD = 'telephone'
    REQUIRED_FIELDS = []    # 这里是创建createsuperuser时指定需要哪些字段,为空,说明需要上面的USERNAME_FIELD值与password字段
    objects = UserManager()

    def get_full_name(self):
        return self.username
    def get_short_name(self):
        return self.username

settings配置文件中配置:

AUTH_USER_MODEL = 'book.User'

数据迁移后在数据中生成字段有:id, password, last_login, is_superuser, username , email, telephone, is_actiave

创建数据与验证数据:

def index(request):
    telephone = '19976959220'
    password = '123456'
    username = 'ginvip'
    # user = User.objects.create_user(telephone = telephone,password = password, username = username) # 创建数据
    user = authenticate(request, username = telephone, password = password)  # 数据验证
    if user:
        print(user)
        print('验证成功')
    else:
        print('验证失败')
    return HttpResponse('OK')

2.5 获取用户模型类

from django.contrib.auth import get_user_model  # 会从settings配置文件中获取 AUTH_USER_MODEL值
user = get_user_model()
发布了45 篇原创文章 · 获赞 3 · 访问量 1520

猜你喜欢

转载自blog.csdn.net/pcn01/article/details/103894425