django_auth模块

auth模块的介绍

  • auth模块是django自带的用户认证模块

  • 在开发一个网站的时候,无可避免的需要设计实现网站的用户系统。需要实现包括用户注册、用户登录、用户认证、注销、修改密码等功能,自己写起来很麻烦,Django作为一个完美主义者的终极框架,当然也会想到用户的这些痛点。它内置了强大的用户认证系统--auth,它默认使用 auth_user 表来存储用户数据。

  • 案例说明

在创建好一个django项目之后直接执行数据库的迁移命令,就会在数据库中自动生成很多表
- django_session
- auth_user

我们知道django启动之后就可以直接访问admin路由,需要输用户名和密码,数据参考的就是auth_user表,并且必须是管理员用户才能进入(在表中对应的字段就是is_superuser)

在django后端创建超级用户(管理员)的方式
- python manage.py creatsuperuser(tools--->run manage.py task)
'''
邮箱可以不写,密码长度最短8位
创建完成之后就可以登陆django后台管理了
'''

auth模块的基本使用

  • 基于auth模块校验用户登陆
- 后端代码
from django.shortcuts import render
from django.contrib import auth

def login(request):
	if request.method == 'POST':
		username = request.POST.get('username')
		password = request.POST.get('password')
		'''
		获取前端用户输入的数据之后,需要去后端进行校验
		问题1:想要校验就必须拿到auth_user表中的数据进行比对
		问题2:auth_user表中的密码是密文的,如何进行比对?
		解决方式:auth模块,代码如下
		'''
        uer_obj = auth.authenticate(request,username=username,password=password)
        '''
        通过auth模块校验数据内部发生的事情
        1 自动查找auth_user表
        2 自动给用户输入的密码进行加密然后再进行比对
        3 注意:括号内必须同时传入用户名和密码,不能只传用户名,否则会报错
        '''
        print(user_obj) # 该方法会有一个返回值,如果用户校验成功就返回该用户对象,如果校验不成功就返回None
        if user_obj:
            print(res.username)
            print(res.password)
     return render(request,'login.html',locals())

- login.html
<body>
<form action="" method="post">
    {% csrf_token %}
    <p>username<input type="text" name="username"></p>
    <p>password<input type="password" name="password"></p>
    <input type="submit">
</form>
</body>
  • 基于auth模块记录用户登陆状态
def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        res = auth.authenticate(request,username=username,password=password)
        
        if res:
        	# 记录用户的登陆状态,类似于request.session[key] = user_obj
        	# 只要执行了该方法,在任意地方都可以通过request.user获取到当前登陆的用户对象
        	# auth模块将django_session里面查找到的用户封装到request中,可以通过request.user获取到当前登陆的用户对象
            auth.login(request,user=res)
    return render(request,'login.html')
  • 判断当前用户是否登陆
def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        res = auth.authenticate(request,username=username,password=password)
        # 判断用户是否已经登陆了,返回结果是布尔值CallableBool(True)
        print(request.user.is_authenticated)
        
        if res:
            auth.login(request,user=res)
    return render(request,'login.html')
  • 校验用户是否登陆装饰器
from django.contrib.auth.decorators import login_required
# 局部配置
@login_required(login_url='/login/') # 当用户没有登陆的时候让用户跳转到'/login/',是局部配置
def home(request):
    return HttpResponse('home')
    
    
# 全局配置
-在settings.py文件中配置全局跳转
# 没有登陆跳转到指定的页面
LOGIN_URL = '/login/'

from django.contrib.auth.decorators import login_required
# 全局配置
@login_required
def home(request):
    return HttpResponse('home')
    
    
全局与局部配置对比
	1.如果局部和全局都有 该听谁的?
    局部 > 全局
	2.局部和全局哪个好呢?
    全局的好处在于无需重复写代码 但是跳转的页面却很单一
    局部的好处在于不同的视图函数在用户没有登陆的情况下可以跳转到不同的页面 
  • 用户修改密码
- 如何进行原密码的比对
request.user.check_password(old_password)
- 修改用户信息
request.user.set_password(new_password)  # 仅仅是在修改对象的属性
request.user.save()  # 这一步才是真正的操作数据库
  • 注销用户登陆
auth.logout(request) 
  • 注册 --- auth_user表写入数据
User.objects.create(username=username,password=password)  # 写入数据  不能用create 密码没有加密处理
# 创建普通用户
User.objects.create_user(username=username,password=password)
# 创建超级用户(了解):使用代码创建超级用户 邮箱是必填的 而用命令创建则可以不填
User.objects.create_superuser(username=username,email='123@qq.com',password=password)

如何扩展auth_user表

这内置的认证系统这么好用,但是auth_user表字段都是固定的那几个,我在项目中没法拿来直接使用啊!

比如,我想要加一个存储用户手机号的字段,怎么办?

聪明的你可能会想到新建另外一张表然后通过一对一和内置的auth_user表关联,这样虽然能满足要求但是有没有更好的实现方式呢?

答案是当然有了。

我们可以通过继承内置的 AbstractUser 类,来定义一个自己的Model类。

这样既能根据项目需求灵活的设计用户表,又能使用Django强大的认证系统了

from django.contrib.auth.models import AbstractUser
class UserInfo(AbstractUser):
    """
    如果继承了AbstractUser
    那么在执行数据库迁移命令的时候auth_user表就不会再创建出来了
    而UserInfo表中会出现auth_user所有的字段外加自己扩展的字段
    这么做的好处在于你能够直接点击你自己的表更加快速的完成操作及扩展
    
    前提:
        1.在继承之前没有执行过数据库迁移命令
            auth_user没有被创建,如果当前库已经创建了那么你就重新换一个库
        2.继承的类里面不要覆盖AbstractUser里面的字段名
            表里面有的字段都不要动,只扩展额外字段即可
        3.需要在配置文件中告诉django你要用UserInfo替代auth_user(******)
            AUTH_USER_MODEL = 'app01.UserInfo'
                                '应用名.表名'
        4.如果自己写表替代了auth_user那么auth模块的功能还是照常使用,参考的表页由原来的			auth_user变成了UserInfo
    """
    nid = models.AutoField(primary_key=True)
    phone = models.CharField(max_length=11, null=True, unique=True)
    
    def __str__(self):
        return self.username

按上面的方式扩展了内置的auth_user表之后,一定要在settings.py中告诉Django,我现在使用我新定义的UserInfo表来做用户认证。写法如下:

# 引用Django自带的User表,继承使用时需要设置
AUTH_USER_MODEL = "app名.UserInfo"
posted @ 2020-06-09 21:27  微信搜索-程序媛小庄  阅读(198)  评论(0编辑  收藏  举报