django用户认证组件auth
简介
django提供了一个非常好用的组件,这个组件主要负责用户登录认证的全套功能,它就是auth组件。
有了auth组件,我们就不需要再手动写登录校验装饰器,不需要再手动设置session保存用户状态。
django项目执行数据库迁移命令后会生成一堆默认的表,其中就包括auth_user表,auth组件和这张表有密切关系。
另外,django项目默认都会有一个admin后台管理系统,登录的用户信息是保存在auth_user表中的;且用户分为普通用户和超级用户,只有超级用户可以登录admin后台管理系统。
# 命令行方式创建一个超级用户
python3 manage.py createsuperuser
auth模块基本使用
常用方法
登录校验:auth.authenticate()
user_obj = auth.authenticate(request,
username=username,
password=password)
print(user_obj)
print(user_obj.username)
# 注意点:
1.authenticate()括号内必须同时传入用户名和密码
2.密码自动加密校验
3.校验成功,返回当前对象,校验失败返回None
保存用户状态:auth.login()
auth.login(request, user_obj)
# 注意点:
1.该方法需要request、和当前登陆用户对象俩个方法
2.该方法自动设置session,类似于request.session[key] = user_obj
3.只要执行了该方法后,就可以在任何地方通过request.user获取到当前登陆的用户对象
获取当前登陆用户对象
request.user
判断当前用户是否登陆:
request.user.is_authenticated #补充:is_authenticated其实是方法,只不过被property装饰了可以当属性用
登录装饰器
from django.contrib.auth.decorators import login_required
@login_required(login_url='/login/')
def index(request):
pass
# 注意点:
1.未登录时跳转到的页面需要手动设置;设置分局部设置和全局设置。
2.局部设置,直接在装饰器内通过参数login_url指定
3.全局设置,在配置文件中通过参数LOGIN_URL = '/login/'设置
4.装饰器帮我们在跳转后的url后面添加了target_url,我们在login的视图函数中手动捕获它
4.局部设置的优先级高与全局的设置
#5.全局的好处在于无需重复写代码 但是跳转的页面却很单一
#6.局部的好处在于不同的视图函数在用户没有登陆的情况下可以跳转到不同的页面
校验密码是否正确:
request.user.check_password(old_password)
修改密码:
request.user.set_password(new_password)
request.user.save()
# 注意点:
需要两个,第一步仅仅是在修改对象的属性;第二步才是真正的操作数据库
注销:
auth.logout(request) # 相等于 request.session.flush()
注册
# 方式1:操作auth_user表写入数据(不推荐,密码没有加密处理)
from django.contrib.auth.models import User
User.objects.create(username=username, password=password)
# 方式2:创建普通用户
User.objects.create_user(username=username, password=password)
# 方式3:创建超级用户
User.objects.create_superuser(username=username,
email='123@qq.com',
password=password)
#注意:
1.方式2和方式3创建成功后返回当前对象
2.使用代码创建超级用户,邮箱是必填的,而用命令创建则可以不填
总结
auth.authenticate() # 校验登录用户用户名和密码
auth.login(request, user_obj) # 登陆后保存登录状态
auth.logout(request) # 注销
# 保存登录状态后,可以在任何位置通过request.user获取到当前登陆的用户对象
# 获取当前对象后,可以通过点的方式获取对象属性和方法
request.user.is_authenticated() # 判断对象是否登录(is_authenticated其实是方法,只不过被property装饰了也可以当属性用)
request.user.check_password() # 查看用户密码是否正确
request.user.set_password() # 设置密码(更新密码)
request.user.save() # 设置密码一定要save后才有效
# 其他方法
User.objects.create_user() # 创建普通用户
login_required # 登录校验装饰器
# 总结:使用auth就使用全套的
优点:封装了大量的内置方法,使用方便
缺点:耦合程度高,只能全套使用,灵活性差
扩展auth_user表
# 需求:
使用auth组件的功能,同时又需要额外新增一些其他新字段
解决方式1(不推荐)
利用表和表的外键约束关系,新建一张用户表和auth_user
表一对一外键关联。
from django.db import models
from django.contrib.auth.models import User
class UserDetail(models.Model):
phone = models.BigIntegerField()
user = models.OneToOneField(to='User')
解决方式2(推荐)
利用类的继承关系,定义一个新类继承AbstractUser
,再增加几个新属性
from django.db import models
from django.contrib.auth.models import AbstractUser
class UserInfo(AbstractUser):
phone = models.BigIntegerField()
方式2的好处
- 自己写一个继承了
AbstractUser
的表UserInfo
,执行数据库数据库迁移命令的时候auth_user
表就不会再创建出来了 - 而
UserInfo
表中会出现auth_user
所有的字段外加自己扩展的字段 - 这么做的好处在于你能够直接点击你自己的表更加快速的完成操作及扩展
- 自己写表
UserInfo
替代了auth_user
,那么auth
模块的功能还是照常使用,参考的表页由原来的auth_user
变成了UserInfo
方式2的前提
-
在继承之前没有执行过数据库迁移命令;即如果已经有了
auth_user
表则无法再使用该方式。 -
继承的类里面不要覆盖
AbstractUser
里面的字段名;表里面有的字段都不要动,只扩展额外字段即可。 -
需要在配置文件中告诉django你要用
UserInfo
替代auth_user
# 配置方式 AUTH_USER_MODEL = 'app01.UserInfo' # '应用名.表名'