我們在開發(fā)一個網(wǎng)站的時候施蜜,我可避免的需要設(shè)計實現(xiàn)網(wǎng)站的用戶系統(tǒng)雌隅。此時我們需要實現(xiàn)包括用戶注冊恰起、用戶登錄、用戶認證检盼、注銷肯污、修改密碼等一系列功能。Django作為一個完美主義者的終極框架吨枉,當然也會想到用戶的這些需求蹦渣,它內(nèi)置了強大的用戶認證系統(tǒng)——auth,他默認使用auth_user 表來存儲用戶數(shù)據(jù)貌亭。
新建用戶
創(chuàng)建用戶最直接的方法是使用包含 create_user()
的函數(shù):
from django.contrib.auth.models import User #引入User模塊
user = User.objects.create_user(username=username, password=password) #新建普通用戶
user = User.objects.create_superuser(username=username, password=password) #創(chuàng)建超級用戶
user.sava() #創(chuàng)建用戶并提交
認證用戶
使用 authenticate()
來驗證用戶柬唯。它使用 username
和 password
作為參數(shù)來驗證,對每個身份驗證后端進行檢查属提。如果后端驗證有效权逗,則返回一個User
對象冤议,否則將返回 None
斟薇。
from django.contrib.auth import authenticate #引入authenticate模塊
user = authenticate(username='username', password='password')
if user is not None:
# A backend authenticated the credentials
else:
# No backend authenticated the credentials
# 認證用戶的賬戶密碼是否有效, 若有效則返回代表該用戶的user對象, 若無效則返回None.
修改密碼和密碼驗證
Django 不會在用戶模型里保存原始(明文)密碼,而只會存儲哈希值 恕酸。因此堪滨,請不要試圖直接操作用戶的密碼,這就是創(chuàng)建用戶需要輔助函數(shù)的原因蕊温。
from django.contrib.auth.models import User
user = User.objects.get(username='username')
user.set_password('new password')
user.save()
check_password(raw_password)
auth 提供的一個檢查密碼是否正確的方法袱箱,需要提供當前請求用戶的密碼。密碼爭取返回True义矛,否則返回Fale发笔。
一個修改密碼功能的簡單示例:
@login_required
def set_password(request):
user = request.user
err_msg = ''
if request.method == 'POST':
old_password = request.POST.get('old_password', '')
new_password = request.POST.get('new_password', '')
repeat_password = request.POST.get('repeat_password', '')
# 檢查舊密碼是否正確
if user.check_password(old_password):
if not new_password:
err_msg = '新密碼不能為空'
elif new_password != repeat_password:
err_msg = '兩次密碼不一致'
else:
user.set_password(new_password)
user.save()
return redirect("/login/")
else:
err_msg = '原密碼輸入錯誤'
content = {
'err_msg': err_msg,
}
return render(request, 'set_password.html', content)
用戶如何登陸
如果有一個已驗證的用戶想附加到當前會話(session)中,將通過 login()
函數(shù)完成凉翻。
要在視圖中讓用戶登錄了讨,使用 login()
。它需要 HttpRequest
對象和 User
對象。通過 Django 的 session 框架前计, login()
會在 session 中保存用戶的ID胞谭。
注意,在匿名會話期間設(shè)置的任何數(shù)據(jù)都會在用戶登錄后保留在會話中男杈。
from django.contrib.auth import authenticate, login
def tologin(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
# Redirect to a success page.
...
else:
# Return an 'invalid login' error message.
...
用戶如何登出
logout(request)
如果已經(jīng)通過 django.contrib.auth.login()
登錄的用戶想退出登錄丈屹,可以在視圖中使用 django.contrib.auth.logout()
。需要傳入 HttpRequest
對象伶棒,并且該函數(shù)不會返回值旺垒。
from django.contrib.auth import logout
def tologout(request):
logout(request)
# Redirect to a success page.
注意,如果用戶未登錄苞冯,logout()
不會報錯袖牙。
調(diào)用 logout()
后,當前請求的會話數(shù)據(jù)會被全部清除舅锄。這是為了防止其他使用同一個瀏覽器的用戶訪問前一名用戶的會話數(shù)據(jù)鞭达。如果想在登出后立即向用戶提供的會話中放入任何內(nèi)容,請在調(diào)用 django.contrib.auth.logout()
之后執(zhí)行此操作皇忿。
限制對未登錄用戶的訪問
限制訪問頁面最原始的辦法就是檢查 request.user.is_authenticated
并重定向到登錄頁面畴蹭。
from django.conf import settings
from django.shortcuts import redirect
def my_view(request):
if not request.user.is_authenticated:
return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
# ...
或者顯示一個錯誤信息:
from django.shortcuts import render
def my_view(request):
if not request.user.is_authenticated:
return render(request, 'myapp/login_error.html')
# ...
login_required 裝飾器
from django.contrib.auth.decorators import login_required
@login_required
def my_view(request):
...
auth_user數(shù)據(jù)表字段詳解
Django中使用的模型User來自于Django的內(nèi)置模型,在數(shù)據(jù)庫中對應(yīng)的數(shù)據(jù)表為auth_user鳍烁。該表有以下字段:
字段 | 說明 |
---|---|
id | int類型叨襟,數(shù)據(jù)表主鍵 |
password | varchar類型,用戶密碼 |
last_lgoin | datetime類型幔荒,最近一次登錄時間 |
is_superuser | tinyint類型糊闽,是否為超級用戶 |
username | varchar類型,用戶賬號 |
first_name | varchar類型爹梁,用戶的名字 |
last_name | varchar類型右犹,用戶的姓氏 |
電子郵件 | |
is_staff | 判斷用戶是否可以可以登錄Admin系統(tǒng) |
is_active | tinyint類型,判斷該用戶的狀態(tài)是否被激活 |
date_joined | datetime類型姚垃,賬號的創(chuàng)建時間 |
擴展默認的auth_user表
內(nèi)置的認證系統(tǒng)這么好用念链,但是auth_user表字段都是固定的那幾個,我在項目中沒法拿來直接使用积糯!這時我們可以通過繼承內(nèi)置的 AbstractUser 類掂墓,來定義一個自己的Model類。這樣既能根據(jù)項目需求靈活的設(shè)計用戶表看成,又能使用Django強大的認證系統(tǒng)了君编。
from django.contrib.auth.models import AbstractUser
class UserInfo(AbstractUser):
"""
用戶信息表
"""
phone = models.CharField(max_length=11, unique=True)
qq_num = models.CharField(max_length=11, unique=True)
def __str__(self):
return self.username
注意:按上面的方式擴展了內(nèi)置的auth_user表之后,一定要在settings.py中告訴Django川慌,使用我新定義的UserInfo表來做用戶認證啦粹。寫法如下:
AUTH_USER_MODEL = "app名.UserInfo"
然后去數(shù)據(jù)庫里面查看一下偿荷,如圖