django之auth模組
1 auth模組是什麼
Auth模組是Django自帶的使用者認證模組:
我們在開發一個網站的時候,無可避免的需要設計實現網站的使用者系統。此時我們需要實現包括使用者註冊、使用者登入、使用者認證、登出、修改密碼等功能,這還真是個麻煩的事情呢。
Django作為一個完美主義者的終極框架,當然也會想到使用者的這些痛點。它內建了強大的使用者認證系統--auth,它預設使用 auth_user 表來儲存使用者資料。
其實我們在建立好一個django專案之後直接執行資料庫遷移命令會自動生成很多表
python3 manage.py makemigrations
python3 manage.py migrate
django_session
auth_user等
django在啟動之後就可以直接訪問admin路由,需要輸入使用者名稱和密碼,資料參考的就是auth_user表, 並且還必須是管理員使用者才能進入
建立超級使用者(管理員)
python3 manage.py createsuperuser
auth模組要用就要全套,不然可能會出一些奇奇怪怪的問題
2 auth模組常用方法
from django.contrib import auth
2.1 authenticate()
提供了使用者認證功能,即驗證使用者名稱以及密碼是否正確,一般需要username 、password兩個關鍵字引數。
如果認證成功(使用者名稱和密碼正確有效),便會返回一個 User 物件。
認證失敗,返回None
authenticate()會在該 User 物件上設定一個屬性來標識後端已經認證了該使用者,且該資訊在後續的登入過程中是需要的
登入功能:
views.py
from django.shortcuts import render
# Create your views here.
from django.contrib import auth
def login(request):
if request.method=='POST':
username = request.POST.get('username')
password = request.POST.get('password')
user_obj = auth.authenticate(request,username=username,password=password)
# print(user_obj,type(user_obj))
# print(user_obj.username)
# print(user_obj.password)
if user_obj:
auth.login(request,user_obj)
return redirect('/home/')
return render(request,'login.html')
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <form action="" method="post"> {% csrf_token %} <p>username:<input type="text" name="username"></p> <p>password:<input type="text" name="password"></p> <input type="submit"> </form> </body> </html>
2.2 儲存使用者狀態:login(Request, user)
類似於request.session[key] = user_obj
執行了該方法 你就可以在任何地方通過request.user獲取到當前登陸的使用者物件
if user_obj: auth.login(request,user_obj) return redirect('/home/')
def home(request): print(request.user) return HttpResponse('home')
獲取當前登陸使用者 : request.user
自動去django_session表中查詢相應使用者給你request.user中
登入使用者:使用者物件
未登入:AnonymousUser(匿名使用者)
2.3is_authenticated用來判斷當前使用者是否登入
def home(request): print(request.user.is_authenticated) return HttpResponse('home')
2.4 校驗使用者是否登陸裝飾器
from django.contrib.auth.decorators import login_required
區域性配置: @login_required(login_url='/login/') 括號內是指向哪個url
from django.contrib.auth.decorators import login_required @login_required(login_url='/login/') def index(request): return HttpResponse('index')
全域性配置:LOGIN_URL = '/login/'
1.如果區域性和全域性都有 ,聽區域性的
優先順序 區域性 > 全域性
2.區域性和全域性哪個好呢?
全域性的好處在於無需重複寫程式碼 但是跳轉的頁面卻很單一
區域性的好處在於不同的檢視函式在使用者沒有登陸的情況下可以跳轉到不同的頁面
2.5 比對原密碼
request.user.check_password(old_password)
2.6 修改密碼
request.user.set_password(new_password) # 僅僅是在修改物件的屬性 request.user.save() # 這一步才是真正的操作資料庫
set_password.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <form action="" method="post"> {% 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"> </form> </body> </html>
views.py中:
@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) if is_right: request.user.set_password(new_password) request.user.save() return redirect('/login/') return render(request,'set_password.html',locals())
2.7 登出 :auth.logout(request)
類似於request.session.flush()
@login_required def logout(request): auth.logout(request) #request.session.flush() return redirect('/login/')
2.8 註冊 :from django.contrib.auth.models import User
建立普通使用者:不能登入admin後臺
from django.contrib.auth.models import User User.objects.create_user(username=username,password=password)
建立超級使用者(瞭解):使用程式碼建立超級使用者 郵箱是必填的 而用命令建立則可以不填
User.objects.create_superuser(username=username,email='[email protected]',password=password) 郵箱必須新增
register.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <form action="" method="post"> {% csrf_token %} <p>username:<input type="text" name="username"></p> <p>password:<input type="text" name="password"></p> <input type="submit"> </form> </body> </html>
views.py
from django.contrib.auth.models import User def register(request): if request.method=='POST': username = request.POST.get('username') password = request.POST.get('password') User.objects.create_user(username=username,password=password) return redirect('/login/') return render(request,'register.html')
3User物件的屬性
User物件屬性:username, password
is_staff : 使用者是否擁有網站的管理許可權.
is_active : 是否允許使用者登入, 設定為 False,可以在不刪除使用者的前提下禁止使用者登入。
4擴充套件auth_user表
這內建的認證系統這麼好用,但是auth_user表字段都是固定的那幾個,我在專案中沒法拿來直接使用啊!
比如,我想要加一個儲存使用者手機號的欄位,怎麼辦?
聰明的你可能會想到新建另外一張表然後通過一對一和內建的auth_user表關聯,這樣雖然能滿足要求但是有沒有更好的實現方式呢?
答案是當然有了。
我們可以通過繼承內建的 AbstractUser 類,來定義一個自己的Model類。
這樣既能根據專案需求靈活的設計使用者表,又能使用Django強大的認證系統了
models.py
from django.db import models from django.contrib.auth.models import User,AbstractUser # Create your models here. class UserInfo(AbstractUser): phone = models.BigIntegerField(null=True)
settings.py
AUTH_USER_MODEL = 'app01.UserInfo'
你如果自己寫表替代了auth_user那麼
auth模組的功能還是照常使用,參考的表頁由原來的auth_user變成了UserInfo