目錄
一、Auth模塊引入
二、創建超級用戶(管理員)
三、依賴于auth_user表完成登錄注冊功能
【1】基礎登陸
【2】保存用戶狀態
【3】登錄后跳轉
(1)? 登錄后才能訪問頁面 -- 局部配置
(2)? 登錄后才能訪問頁面 -- 全局配置
(3)?小結
三、修改密碼
四、注銷
五、注冊功能
六、方法總結
【1】校驗密碼是否正確
【2】保存用戶狀態
【3】判斷當前用戶是否登錄
【4】獲取當前登錄的用戶
【5】檢驗用戶是否登錄裝飾器
【6】校驗原密碼
【7】修改密碼
【8】注銷登錄用戶
【9】注冊
七、擴展?auth_user?表
【1】方式一
【2】方式二
一、Auth模塊引入
- 我們在創建一個Django項目之后,直接執行數據庫遷移命令會自動生成很多表
- django_session
- auth_user
- Django在啟動之后就可以直接訪問admin路由,需要輸入用戶名和密碼,數據參考的就是auth_user表,并且必須是管理員用戶才能進入
二、創建超級用戶(管理員)
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
三、依賴于auth_user表完成登錄注冊功能
【1】基礎登陸
- 路由?
path('login/', views.login),
- 前端
<form action="" method="post">{# 取消crsf校驗 #}{% csrf_token %}<p>username:<input type="text" name="username"></p><p>password:<input type="text" name="password"></p><input type="submit" class="btn btn-success">
</form>
- 后端?
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 authuser_obj = auth.authenticate(request, username=username, password=password)# [1] 用戶名和密碼正確的情況下print(user_obj) # dream ---- 這是用戶對象內部封裝的一個方法 __str__ 方法print(user_obj.username) # dreamprint(user_obj.password) # pbkdf2_sha256$260000$011PbZAjKIWBfAUJ61Rcyn$vNUYq5L70/ljTLEeJ2dBJtDTEKFDTKzFioFPjZYMdU4=# [2] 用戶名和密碼不正確的情況下print(user_obj) # None ---- 如果數據不符合則返回None'''【1】自動查找 auth_user 表【2】自動給密碼加密進行比對注意事項:參數必須傳入用戶名和密碼不能只傳入一個用戶名(一步就幫助我們篩選出用戶數據)'''return render(request, 'login.html')
【2】保存用戶狀態
- 如果使用auth模塊,就使用其中所有封裝好的方法
- 如果不想使用,就單獨封裝方法,不要調用其中的方法
- auth.login(request, user_obj)
- 類似于 request.session[key] = user_obj
- 只要執行了上面的方法,就可以在任何地方通過 request.user 獲取當前用戶的登錄對象
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 authuser_obj = auth.authenticate(request, username=username, password=password)# 判斷當前用戶是否存在 --- 存在則有值,不存在則返回Noneif user_obj:# 保存用戶狀態auth.login(request, user_obj) # 類似于 request.session[key] = user_obj# 只要執行了上面的方法,就可以在任何地方通過 request.user 獲取當前用戶的登錄對象'''【1】自動查找 auth_user 表【2】自動給密碼加密進行比對注意事項:參數必須傳入用戶名和密碼不能只傳入一個用戶名(一步就幫助我們篩選出用戶數據)'''return render(request, 'login.html')
【3】登錄后跳轉
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 authuser_obj = auth.authenticate(request, username=username, password=password)# 判斷當前用戶是否存在 --- 存在則有值,不存在則返回Noneif 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()) # 匿名用戶返回 Falsereturn HttpResponse("OK")
(1)? 登錄后才能訪問頁面 -- 局部配置
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()) # 匿名用戶返回 Falsereturn HttpResponse("OK")
http://127.0.0.1:8000/accounts/login/?next=/home/
(2)? 登錄后才能訪問頁面 -- 全局配置
- 在?
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()) # 匿名用戶返回 Falsereturn HttpResponse("OK")@login_required
def index(request):return HttpResponse("index")
(3)?小結
-
局部/全局優先級
- 局部大于全局
-
各自的優點
- 全局的好處在于無需書寫重復的代碼,但是頁面的跳轉很單一
- 局部的好處是在于不同的視圖函數再用戶沒有登陸的情況下可以跳轉到不同的頁面
三、修改密碼
- 路由
# 修改密碼
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 或者 Falseif is_right:# 修改密碼request.user.set_password(confirm_password) # 僅僅在修改對象的屬性# 修改完密碼后進行保存數據request.user.save()return redirect('/login/')return render(request, 'set_password.html', locals())
- 前端?
<form action="" method="post">{# 取消crsf校驗 #}{% csrf_token %}<p>username:<input type="text" name="username" disabled value="{{ request.user.username }}"></p><p>old_password:<input type="text" name="old_password"></p><p>new_password:<input type="text" name="new_password"></p><p>confirm_password:<input type="text" name="confirm_password"></p><input type="submit" class="btn btn-success">
</form>
四、注銷
- 路由
# 注銷用戶
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')
六、方法總結
【1】校驗密碼是否正確
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
【2】保存用戶狀態
# 判斷當前用戶是否存在 --- 存在則有值,不存在則返回None
if user_obj:# 保存用戶狀態auth.login(request, user_obj) # 類似于 request.session[key] = user_obj# 只要執行了上面的方法,就可以在任何地方通過 request.user 獲取當前用戶的登錄對象
【3】判斷當前用戶是否登錄
# 判斷用戶是否登陸
# 匿名用戶返回 False 正常用戶返回 True
print(request.user.is_authenticated())
【4】獲取當前登錄的用戶
print(request.user)
# 登陸成功: dream ---- 這是用戶對象內部封裝的一個方法 __str__ 方法
# 未登錄訪問: AnonymousUser ---- 匿名用戶
# 本質上是自動去django_session里面查找到當前用戶對象,然后封裝到 request.user 中
【5】檢驗用戶是否登錄裝飾器
from django.contrib.auth.decorators import login_required
-
(1) 局部配置
-
(2) 全局配置
-
(3) 全局/局部的優缺點
【6】校驗原密碼
# 校驗舊密碼是否相同
is_right = request.user.check_password(old_password) # 內部自己加密密碼進行比對
# 返回的結果為 True 或者 False
【7】修改密碼
# 修改密碼
request.user.set_password(confirm_password) # 僅僅在修改對象的屬性
# 修改完密碼后進行保存數據
request.user.save()
【8】注銷登錄用戶
auth.logout(request)
# 清空當前登錄用戶的數據 ----- request.session.flush()
【9】注冊
# 操作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
?表
【1】方式一
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_userAUTH_USER_MODEL = 'app01.UserInfo' ---'應用名.表名''''phone = models.CharField(max_length=32)
- 需要再配置文件中聲明 Django 要使用 UserInfo 替代 auth_user
AUTH_USER_MODEL = 'app01.UserInfo' ?---'應用名.表名'
- 如果自己寫表代替了 auth_user
- auth模塊功能正常使用,參考的表也由 auth_user 變成了 UserInfo
【2】方式二
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)