目录
一、Auth模块引入
二、创建超级用户(管理员)
三、依赖于auth_user表完成登录注册功能
【1】基础登陆
【2】保存用户状态
【3】登录后跳转
(1) 登录后才能访问页面 -- 局部配置
(2) 登录后才能访问页面 -- 全局配置
(3) 小结
三、修改密码
四、注销
五、注册功能
六、方法总结
【1】校验密码是否正确
【2】保存用户状态
【3】判断当前用户是否登录
【4】获取当前登录的用户
【5】检验用户是否登录装饰器
【6】校验原密码
【7】修改密码
【8】注销登录用户
【9】注册
七、扩展 auth_user 表
【1】方式一
【2】方式二
python3 manage.py createsuperuser
E:\Python39\python.exe "E:\Pycharm\PyCharm 2023.1.3\plugins\python\helpers\pycharm\django_manage.py" createsuperuser "E:/Old Boy/django_project/day14"
Tracking file by folder pattern: migrations
Username (leave blank to use 'administrator'): dream
Email address:
Warning: Password input may be echoed.
Password: 521
Warning: Password input may be echoed.
Password (again): 521
This password is too short. It must contain at least 8 characters.
Bypass password validation and create user anyway? [y/N]: This password is entirely numeric.
y
Superuser created successfully.
Process finished with exit code 0
path('login/', views.login),
from django.shortcuts import render
from django.contrib import auth
# Create your views here.
def login(request):
if request.method == 'POST':
# (1) 取到前端输入的用户名和密码
username = request.POST.get('username')
password = request.POST.get('password')
# (2) 进行用户名和密码的校验
# 从用户表中获取数据
# --- 1、表如何获取
# --- 2、表中的密码是密文,如何比对
# 导入 auth 校验模块 : from django.contrib import auth
user_obj = auth.authenticate(request, username=username, password=password)
# [1] 用户名和密码正确的情况下
print(user_obj) # dream ---- 这是用户对象内部封装的一个方法 __str__ 方法
print(user_obj.username) # dream
print(user_obj.password) # pbkdf2_sha256$260000$011PbZAjKIWBfAUJ61Rcyn$vNUYq5L70/ljTLEeJ2dBJtDTEKFDTKzFioFPjZYMdU4=
# [2] 用户名和密码不正确的情况下
print(user_obj) # None ---- 如果数据不符合则返回None
'''
【1】自动查找 auth_user 表
【2】自动给密码加密进行比对
注意事项:
参数必须传入用户名和密码
不能只传入一个用户名(一步就帮助我们筛选出用户数据)
'''
return render(request, 'login.html')
from django.shortcuts import render
from django.contrib import auth
# Create your views here.
def login(request):
if request.method == 'POST':
# (1) 取到前端输入的用户名和密码
username = request.POST.get('username')
password = request.POST.get('password')
# (2) 进行用户名和密码的校验
# 从用户表中获取数据
# --- 1、表如何获取
# --- 2、表中的密码是密文,如何比对
# 导入 auth 校验模块 : from django.contrib import auth
user_obj = auth.authenticate(request, username=username, password=password)
# 判断当前用户是否存在 --- 存在则有值,不存在则返回None
if user_obj:
# 保存用户状态
auth.login(request, user_obj) # 类似于 request.session[key] = user_obj
# 只要执行了上面的方法,就可以在任何地方通过 request.user 获取当前用户的登录对象
'''
【1】自动查找 auth_user 表
【2】自动给密码加密进行比对
注意事项:
参数必须传入用户名和密码
不能只传入一个用户名(一步就帮助我们筛选出用户数据)
'''
return render(request, 'login.html')
from django.shortcuts import render, redirect, HttpResponse
from django.contrib import auth
# Create your views here.
def login(request):
if request.method == 'POST':
# (1) 取到前端输入的用户名和密码
username = request.POST.get('username')
password = request.POST.get('password')
# (2) 进行用户名和密码的校验
# 从用户表中获取数据
# --- 1、表如何获取
# --- 2、表中的密码是密文,如何比对
# 导入 auth 校验模块 : from django.contrib import auth
user_obj = auth.authenticate(request, username=username, password=password)
# 判断当前用户是否存在 --- 存在则有值,不存在则返回None
if user_obj:
# 保存用户状态
auth.login(request, user_obj) # 类似于 request.session[key] = user_obj
# 只要执行了上面的方法,就可以在任何地方通过 request.user 获取当前用户的登录对象
# 登陆成功后跳转页面
return redirect('/home/')
'''
【1】自动查找 auth_user 表
【2】自动给密码加密进行比对
注意事项:
参数必须传入用户名和密码
不能只传入一个用户名(一步就帮助我们筛选出用户数据)
'''
return render(request, 'login.html')
def home(request):
print(request.user) # dream ---- 这是用户对象内部封装的一个方法 __str__ 方法
print(request.user)
# 登陆成功: dream ---- 这是用户对象内部封装的一个方法 __str__ 方法
# 未登录访问: AnonymousUser ---- 匿名用户
# 本质上是自动去django_session里面查找到当前用户对象,然后封装到 request.user 中
return HttpResponse("OK")
def home(request):
print(request.user)
# 登陆成功: dream ---- 这是用户对象内部封装的一个方法 __str__ 方法
# 未登录访问: AnonymousUser ---- 匿名用户
# 本质上是自动去django_session里面查找到当前用户对象,然后封装到 request.user 中
# 判断用户是否登陆
print(request.user.is_authenticated()) # 匿名用户返回 False
return HttpResponse("OK")
from django.contrib.auth.decorators import login_required
# 添加装饰器 --- 指定未登录的跳转页面
@login_required(login_url='/login/') # 局部配置
def home(request):
'''用户登录后才能访问的页面'''
print(request.user)
# 登陆成功: dream ---- 这是用户对象内部封装的一个方法 __str__ 方法
# 未登录访问: AnonymousUser ---- 匿名用户
# 本质上是自动去django_session里面查找到当前用户对象,然后封装到 request.user 中
# 判断用户是否登陆
print(request.user.is_authenticated()) # 匿名用户返回 False
return HttpResponse("OK")
http://127.0.0.1:8000/accounts/login/?next=/home/
settings
文件中添加LOGIN_URL = '/login/'
from django.contrib.auth.decorators import login_required
# 添加装饰器 --- 指定未登录的跳转页面
@login_required
def home(request):
'''用户登录后才能访问的页面'''
print(request.user)
# 登陆成功: dream ---- 这是用户对象内部封装的一个方法 __str__ 方法
# 未登录访问: AnonymousUser ---- 匿名用户
# 本质上是自动去django_session里面查找到当前用户对象,然后封装到 request.user 中
# 判断用户是否登陆
print(request.user.is_authenticated()) # 匿名用户返回 False
return HttpResponse("OK")
@login_required
def index(request):
return HttpResponse("index")
局部/全局优先级
各自的优点
# 修改密码
path('set_password/', views.set_password),
@login_required
def set_password(request):
if request.method == 'POST':
old_password = request.POST.get('old_password')
new_password = request.POST.get('new_password')
confirm_password = request.POST.get('confirm_password')
# 先校验两次密是否一致
if new_password == confirm_password:
# 校验旧密码是否相同
is_right = request.user.check_password(old_password) # 内部自己加密密码进行比对
# 返回的结果为 True 或者 False
if is_right:
# 修改密码
request.user.set_password(confirm_password) # 仅仅在修改对象的属性
# 修改完密码后进行保存数据
request.user.save()
return redirect('/login/')
return render(request, 'set_password.html', locals())
# 注销用户
path('login_out/', views.login_out),
@login_required
def login_out(request):
auth.logout(request) # 清空当前登录用户的数据 ----- request.session.flush()
return redirect('/login/')
# 注册用户
path('register/', views.register),
def register(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
confirm_password = request.POST.get('confirm_password')
# 操作auth_user表写入数据
# User.objects.create(username=username, password=confirm_password) # 会写入数据,但是保存的密码是明文的,没有加密
# 创建普通用户
User.objects.create_user(username=username, password=confirm_password)
# 创建超级用户 - 了解 --- 使用代码创建超级用户,邮箱和密码是必填的,而用命令创建可以忽略邮箱
# User.objects.create_superuser(username=username, password=password,email=email)
return render(request, 'register.html')
from django.contrib import auth
# (1) 取到前端输入的用户名和密码
username = request.POST.get('username')
password = request.POST.get('password')
# (2) 进行用户名和密码的校验 ---- 参数必须传用户名和密码
user_obj = auth.authenticate(request, username=username, password=password)
# [1] 用户名和密码正确的情况下
print(user_obj)
# dream ---- 这是用户对象内部封装的一个方法 __str__ 方法
print(user_obj.username)
# dream
print(user_obj.password)
# pbkdf2_sha256$260000$011PbZAjKIWBfAUJ61Rcyn$vNUYq5L70/ljTLEeJ2dBJtDTEKFDTKzFioFPjZYMdU4=
# [2] 用户名和密码不正确的情况下
print(user_obj) # None ---- 如果数据不符合则返回None
# 判断当前用户是否存在 --- 存在则有值,不存在则返回None
if user_obj:
# 保存用户状态
auth.login(request, user_obj) # 类似于 request.session[key] = user_obj
# 只要执行了上面的方法,就可以在任何地方通过 request.user 获取当前用户的登录对象
# 判断用户是否登陆
# 匿名用户返回 False 正常用户返回 True
print(request.user.is_authenticated())
print(request.user)
# 登陆成功: dream ---- 这是用户对象内部封装的一个方法 __str__ 方法
# 未登录访问: AnonymousUser ---- 匿名用户
# 本质上是自动去django_session里面查找到当前用户对象,然后封装到 request.user 中
from django.contrib.auth.decorators import login_required
(1) 局部配置
(2) 全局配置
(3) 全局/局部的优缺点
# 校验旧密码是否相同
is_right = request.user.check_password(old_password) # 内部自己加密密码进行比对
# 返回的结果为 True 或者 False
# 修改密码
request.user.set_password(confirm_password) # 仅仅在修改对象的属性
# 修改完密码后进行保存数据
request.user.save()
auth.logout(request)
# 清空当前登录用户的数据 ----- request.session.flush()
# 操作auth_user表写入数据
# 会写入数据,但是保存的密码是明文的,没有加密
User.objects.create(username=username, password=confirm_password)
# 创建普通用户
User.objects.create_user(username=username, password=confirm_password)
# 创建超级用户 - 了解 --- 使用代码创建超级用户,邮箱和密码是必填的,而用命令创建可以忽略邮箱
User.objects.create_superuser(username=username, password=password,email=email)
auth_user
表from django.db import models
from django.contrib.auth.models import User, 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' ---'应用名.表名'
'''
phone = models.CharField(max_length=32)
- 需要再配置文件中声明 Django 要使用 UserInfo 替代 auth_user
AUTH_USER_MODEL = 'app01.UserInfo' ---'应用名.表名'
from django.db import models
from django.contrib.auth.models import User, AbstractUser
# Create your models here.
# 扩展 auth_user 表
# 第二种方式 : 一对一关系(不推荐)
class UserDetail(models.Model):
phone = models.CharField(max_length=32)
user = models.OneToOneField(to='User', on_delete=models.CASCADE)