Django 之 auth 模塊

Django 內置一個 auth 模塊,幫助用戶實現註冊、登陸、註銷以及修改密碼等功能,幫助開發者省去了不少功夫。html

auth 模塊

在建立模型時,Django內部會生成一個名爲 auth_user 的數據表,用於存儲認證的用戶信息。python

auth 模塊提供了一系列的方法,使用以前須要導入:數據庫

from django.contrib import auth

authenticate() 方法

提供用戶認證功能,驗證用戶名和密碼是否正確等。如驗證成功,則返回一個 User 對象。django

from django.contrib import auth

def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')

         # 用戶認證,驗證用戶名、密碼是否正確,並返回一個 user 對象
         # username、password 字段對應 auth_user 表中相應字段
        user_obj = auth.authenticate(username=username, password=password)

login() 方法

實現用戶登陸功能,會在後臺爲登陸用戶生成 session 數據。session

from django.contrib import auth
auth.login(request, user_obj)

from django.contrib.auth import login
login(request, user_obj)

接收兩個參數,第一個爲 HTTPRequest 對象,以及一個認證過的用戶對象(即 authenticate() 認證過的用戶對象)。app

from django.contrib import auth

def login(request):
    """登陸"""
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')

        # 用戶認證,驗證用戶名、密碼是否正確,並返回一個 user 對象
        user_obj = auth.authenticate(username=username, password=password)
        if user_obj:
            # 將驗證成功的用戶封裝到 request.user 對象中
            auth.login(request, user_obj)
            return redirect('home')
        else:
            return '錯誤信息'
    return render(request, 'login.html')

認證成功的用戶對象,執行 login() 方法,實現登陸功能,不然返回錯誤信息。工具

Tipsui

執行過 login() 方法的用戶對象,就能經過request.user 拿到當前登陸的用戶對象,從而取出用戶的相關信息,不然取得的將是一個匿名用戶對象 AnonymounsUser Object加密

login(request, user_obj)
# 得到當前登陸用戶對象
user = request.user
# 得到當前登陸用戶對象的用戶名
username = request.user.username

logout() 方法

該方法實現註銷功能,清除當前登陸用戶數據庫中的 session 數據,接收一個 HttpRequest 對象,無返回值。url

from django.contrib import auth

def logout(request):
    """註銷"""
    auth.logout(request)
    # 註銷後重定向到登陸頁面
    return redirect('login')

is_authenticated 屬性

判斷當前用戶是否經過認證,爲布爾值。

def home(request):
    """首頁"""
    ret = request.user.is_authenticated
    print(ret)      # True

login_required() 方法

auth 模板提供的一個裝飾器工具,可以便捷地爲某個視圖添加登陸校驗。

  • 若用戶沒有登陸,則默認會跳轉到 accounts/login/,並傳遞當前訪問 url 絕對路徑。
  • 自定義跳轉路徑,只需在 settings.py 中添加:
# 當用戶沒有登陸,訪問某個視圖時將會跳轉到登陸頁面
LOGIN_URL = '/login/'
from django.contrib.auth.decorators import login_required

# 添加裝飾器
@login_required
def home(request):
    """首頁"""

    return render(request, 'home.html')

當用戶訪問 home 頁面時,若沒有登陸則會跳轉到登陸頁面,不然返回 home 頁面。

用戶相關

上面介紹的都是關於登陸相關的,下面將介紹如何建立在 auth_user 中建立用戶,修改密碼,驗證密碼等。

create_superuser() 方法

該方法用於建立一個超級用戶,接收 username、password 兩個必要參數。效果與執行 python manage.py createsuperuser 等同。

from django.contrib.auth.models import User

user_obj = User.objects.create_superuser(username='用戶名',password='密碼',email='郵箱',...)

create_user() 方法

通常狀況 create_superuser() 方法不多使用,最常使用的是create_user() 方法,它將會建立一個普通用戶,常應用於註冊視圖中。

建立用戶所需字段,應與 auth_user 數據表中字段對應。

from django.contrib.auth.models import User

def signup(request):
    # 建立新用戶
    user_obj = User.objects.create_user(username='lila', password='1234')

    return HttpResponse('建立成功')

Tips

新建立的用戶,保存在 auth_user數據表中的密碼是通過加密的。

check_password() 方法

檢查登陸用戶密碼是否正確,須要當前請求用戶的密碼。

from django.contrib.auth.models import User

def signup(request):
    # 建立新用戶
    user_obj = User.objects.create_user(username='lila', password='1234')
    
    ret = user_obj.check_password('123456')
    print(ret)      # False
    return HttpResponse('建立成功')

密碼正確返回 True,不然返回 False。

或者對當前請求的 user 對象校驗原密碼是否正確:

obj = request.user.check_password(raw_password='原始密碼')

set_password() 方法

該方法用於修改密碼,接收要新密碼做爲參數,最後必定要執行 save() 方法保存,不然無效。

def set_password(request):
    """
    修改密碼,request.user 中封裝了已認證且執行了登陸功能的用戶對象
    :param request: 
    :return: 
    """
    request.user.set_password('12')
    password = request.user.password
    request.user.save()
    print(password)

    return HttpResponse('修改爲功')

修改密碼示例

該示例僅適用於已登陸的用戶,在內部修改密碼,未登陸的用戶將跳轉到登陸頁面。

from django.shortcuts import render, redirect, HttpResponse
from django.contrib.auth.decorators import login_required

@login_required
def set_password(request):
    """
    修改密碼,request.user 中封裝了已認證且執行了登陸功能的用戶對象
    :param request:
    :return:
    """
    user = request.user
    ret = {'message': None}
    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:
                ret['message'] = '新密碼不能爲空'
            
            elif new_password != repeat_password:
                ret['message'] = '兩次密碼輸入不一致'
            else:
                user.set_password(new_password)
                user.save()
                return redirect('login')
        else:
            ret['message'] = '原密碼不正確'
    return render(request, 'set_password.html', ret)

auth 模塊拓展

因爲 auth 模板中 auth_user 數據表字段是固定的,所以當咱們使用 auth 模塊,想要添加額外的字段時,就須要對其進行拓展。

拓展方法有兩種:

  • 模型中新增一個表,與 auth_user 表一對一關聯
  • 繼承內置的 AbstractUser 類:經常使用
  1. 模型 models.py 中新建一個類,繼承自 AbstractUser
from django.contrib.auth.models import User, AbstractUser   # 導入 AbstractUser 類


class UserInfo(AbstractUser):
    """
    繼承 AbstractUser
    新增字段:phone、addr
    """
    phone = models.CharField(max_length=11, verbose_name='手機號碼')
    addr = models.CharField(max_length=128, verbose_name='家庭地址')
  1. 配置 settings.py

新增的類繼承 AbstractUser ,拓展後將會覆蓋 auth_user 表,所以須要配置 settings,使默認認證知道要使用哪一種表認證。

# settings.py
# 在最後添加以下代碼
AUTH_USER_MODEL = 'app名.新增的類名'

AUTH_USER_MODEL = 'app.UserInfo'    # 示例
  1. 遷徙數據表
python manage.py makemigrations
python manage.py migrate
  1. 建立用戶

拓展 auth 模塊後,使用的再也不是原來 auth_user 表,而是新表 app.UserInfo 表,所以在建立用戶時應該注意。

# 拓展以前
from django.contrib.auth.models import User
user_obj = User.objects.create_user(username='lila', password='1234')

# 拓展以後
from app.models import UserInfo
user_obj = UserInfo.objects.create_user(username='lila', password='1234')

Tips

  • 若已經遷徙了模型,拓展 auth 模塊時,須要將 migrations 文件夾下文件(如:0001_initial.py文件刪除),不然會報 ValueError: Related model u'app.model' cannot be resolved
  • 若尚未遷徙模型,那麼正常執行便可。
相關文章
相關標籤/搜索