Django 之Auth模塊

来源:https://www.cnblogs.com/huaxiayuyi/archive/2022/10/04/16754258.html
-Advertisement-
Play Games

一、Auth 模塊是什麼 Auth 模塊是Django中自帶的用戶認證模塊。 一個網站系統需要實現用戶註冊、用戶登錄、用戶認證、註銷、修改密碼等功能,Django中內置了強大的認證系統-auth,預設使用 auth_user 表來存儲用戶的數據。 同時Django有一個後臺管理系統(127.0.0. ...


一、Auth 模塊是什麼


Auth 模塊是Django中自帶的用戶認證模塊。

一個網站系統需要實現用戶註冊、用戶登錄、用戶認證、註銷、修改密碼等功能,Django中內置了強大的認證系統-auth,預設使用 auth_user 表來存儲用戶的數據。

同時Django有一個後臺管理系統(127.0.0.1:8000/admin),使用的用戶名和密碼也是這張數據表中的數據。

預設後臺管理的用戶名和密碼是沒有的,需要我們創建一個出來,而且只有超級管理員才能登錄這個頁面,那我們現在就來創建這樣一個超級用戶。

 

二、擴展預設的 auth_user 表


在一個新的項目中,先設計項目的資料庫,表關係,Django 系統內置的認證系統(auth_user表)很好用,但是表欄位都是固定的幾個,無法進行對它擴展。

比如,預設欄位不夠我們使用,我們可以對其進行拓展,存儲用戶手機號、時間等欄位,設置表和表之間關係,怎麼辦?

現在就來設計擴展一下這個表,需要兩步

1 配置settings

在 settings.py 配置文件中增加一句話,告訴Django 使用新定義的 UserInfo 表來做用戶認證的表。

# settings.py
# 聲明使用自定義表作為用戶驗證,聲明格式為: 應用名.表名,繼承使用時需要設置
AUTH_USER_MODEL = 'app.UserInfo'

2 配置models

創建一個自定義類並繼承AbstractUser類,然後編寫 AbstractUser 類中沒有的欄位並且'不能衝突'。

# app/models.py
from django.db import models
# 導入AbstractBaseUser類,繼承AbstractBaseUser類,基本欄位
from django.contrib.auth.models import AbstractUser

class UserInfo(AbstractUser):
    '''
    擴展用戶信息表
    繼承原有的auth_user表欄位
    '''
    nid = models.AutoField(primary_key = True)
    phone = models.CharField(max_length = 11, blank = True, null = True, unique = True, verbose_name = "手機號")
    avatar = models.FileField(upload_to = "avatar", default = "avatar/default.png")
    create_time = models.DateField(auto_now_add = True)
    blog = models.OneToOneField(to = 'Blog', null = True, to_field = 'bid', on_delete = models.CASCADE)
    
    class Meta:
        verbose_name_plural = '用戶表'
    def __str__(self):
        return self.username
    
class Blog(models.Model):
    bid = models.AutoField(primary_key = True)
    site_name = models.CharField(verbose_name = "站點名稱", max_length = 32)
    site_title = models.CharField(verbose_name = "站點標題", max_length = 32)
    site_theme = models.CharField(verbose_name = "站點樣式", max_length = 255)
    def __str__(self):
        return self.site_name

最後,執行兩條資料庫遷移命令。

python manage.py makemigrations
python manage.py migrate

 註意:所在的庫必須是第一次執行遷移命令才可以,若是原本有殘留會 引起異常。

 

三、創建超級用戶


預設後臺管理的用戶名和密碼是沒有的,需要我們創建一個出來,而且只有超級管理員才能登錄這個頁面,那我們現在就來創建這樣一個超級用戶

python manage.py createsuperuser

 

四、Auth 模塊常用方法


1 auth模塊常用方法

from django.contrib import auth

 

2 authenticate()

校驗用戶名和密碼是否正確,可以用來判斷當前是否登錄,也就是否有session數據。

from django.shortcuts import render, HttpResponse, redirect
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)
        if user_obj:
            # 保存用戶狀態
            auth.login(request, user_obj)
            return HttpResponse('OK')
    return render(request, 'login.html')

authenticate方法如果認證成功(用戶名和密碼正確有效,就是去 UserInfo 表中查詢一下是否存在這條記錄),便會返回一個 User 對象,查詢認證失敗返回None。

templates/login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</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>

 

3 login(HttpRequest, user)

該函數接受一個 HttpRequest 對象,以及一個經過認證的 User 對象。

可以在驗證成功後進行登錄,它本質上會在後端為該用戶生成相關session數據。

# 保存用戶狀態,相當於設置 session 值。
# 只要執行了此操作,後面的視圖函數只要能夠拿到request就可以通過 request.user 獲取到當前的用戶對象。
auth.login(request, user_obj)

 

4 logout(request)

該函數接受一個HttpRequest對象,無返回值。註銷。

當調用該函數時,當前請求的session信息會全部清除。該用戶即使沒有登錄,使用該函數也不會報錯。

def logout(request):
    # 類似於request.session.flush()
    auth.logout(request)
    return redirect('/login/')

 

5 is_authenticated()

用來判斷當前請求是否通過了認證。

def home(request):
    print(request.user)  # 用戶對象     AnonymousUser匿名用戶
    print(request.user.is_authenticated())
    if not request.user.is_authenticated():
        return redirect('/home/')
    return redirect('/register/')

 

6 login_requierd()

校驗用戶是否登錄的裝飾器。

判斷當前用戶是否登錄那種方式很複雜,需要再每個功能函數中寫上這麼一段,那麼auth模塊也幫我們提供了一個現成的登錄認證裝飾器。

from django.contrib.auth.decorators import login_required
# auth 模塊提供的登錄裝飾器提供兩個配置: 局部配置和全局配置

# 局部配置
@login_required(login_url='/login/') # 用戶沒有登錄會跳到login頁面
def home(request):
    # if not request.user.is_authenticated:
    #     return redirect('/login/')
    return HttpResponse('歡迎來到home頁面')

# 全局配置:
# settings.py配置文件中配置
LOGIN_URL = '/login/'

# 如果全局配置和局部配置都設置了,那麼會以局部配置優先。

 

7 create_superuser()

auth 提供的一個創建新普通用戶/超級管理員用戶的方法,需要提供必要參數(username、password)等。

from app import models

# 操作auth_user表寫入數據
def register(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        
        # 寫入數據不能用create密碼沒有加密處理
        # models.UserInfo.objects.create(username=username, password=password)  
        
        # 創建普通用戶
        # models.UserInfo.objects.create_user(username=username, password=password)

        # 創建超級用戶(瞭解):使用代碼創建超級用戶 郵箱是必填的 而用命令創建則可以不填
        models.UserInfo.objects.create_superuser(username=username, password=password, email='[email protected]')
    return render(request, 'register.html')

templates/register.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Register</title>
</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>

 

8 check_password()

auth 提供的一個檢查密碼是否正確的方法,需要提供當前請求用戶的密碼。

密碼正確返回True,否則返回False。

 

9 set_password

auth 提供的一個修改密碼的方法,接收新密碼作為參數,校驗原密碼並修改密碼。

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())

templates/set_password.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>密碼修改</title>
</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>

 

五、後臺管理系統配置


1 在該表對應的models類裡面添加一個Meta類

class Meta:
    verbose_name_plural = '用戶表' #指定該表在admin後臺的名字為:用戶表 

 

2 null=True,blank=True的區別

# null=True:  是告訴資料庫該欄位可以為空,admin後臺預設還是不允許為空
# blank=True: admin 後臺該欄位可以為空
phone = models.CharField(max_length = 11, blank = True, null = True, unique = True, verbose_name = "手機號")

 

3 settings.py配置,使django的後臺管理頁面變成中文、設置時區

# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/

LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_L10N = True

USE_TZ = False

 

六、ModelAdmin的常用屬性


1 註冊表

admin.py中只需要 Mode 中的某個類註冊,即可在 Admin 中實現增刪改查的功能。

from django.contrib import admin
from app import models
# Register your models here.

admin.site.register(models.UserInfo)
admin.site.register(models.Blog)

註冊完的結果如下圖所示,點擊表名即可修改表內容。

 

2 list_display欄位展示

  • list_display:列表時,定製顯示的列。
  • 在預設的情況下,Model 在 admin 列表修改頁(Admin ChangeList)只會顯示一列,內容是實例對象的__str__的返回值,如果想要多現實一些列的數據,就可以通過 list_display 屬性來實現。
  • 它除了可以配置 Model 的欄位名之外,還可以接收函數,且這個函數將一個 Model 實例對象作為參數,這個函數也需定義在 ModeAdmin 中。語法格式如下:list_display=[]
  • 在使用 list_display 時需要特別註意它的兩個特性
  • 對於 Foreignkey 類型的欄位,顯示的是 obj.__str__() 返回的值。
  • 不支持 ManyToManyField 類型的欄位,如果需要展示,可以用自定義方法實現。
# 方式一
class UserInfoAdmin(admin.ModelAdmin):
    list_display = ('username', 'email',)
admin.site.register(models.UserInfo, UserInfoAdmin) # 第一個參數可以是列表

# 方式二
@admin.register(models.UserInfo)                    # 第一個參數可以是列表
class UserInfoAdmin(admin.ModelAdmin):
    list_display = ('username', 'email',)

 

3 list_display_links,列表時,定製列可以點擊跳轉。

 

4 list_filter

  • 配置 list_filter 屬性,可以在 Admin 後臺的列表修改頁的右側添加過濾器,且各個過濾條件是 and 的關係。
  • list_filter 是列表或者元組類型,通常使用它會傳遞兩類元素:一個是 Model 的欄位名,另一個是繼承自以下的類(並不常用):django.contrib.admin.SimpleListFilter
  • 對於 Model 的欄位名,欄位類型必須屬於 BooleanField、CharField、DateField、DateTimeField、IntegerField、ForeignKey 或 ManyToManyField 中的一種。同樣也可以使用雙下畫線實現跨表關聯。示例如下所示:list_filter= ['title', 'pub__pubname']

5 list_editable,列表時,可以編輯的列 。

 

cclass UserInfoAdmin(admin.ModelAdmin):
    list_display = ('email', 'create_time', 'phone',)
    list_display_links = ( 'create_time',)
    list_filter = ('email', 'phone',)
    list_editable = ('email', )
admin.site.register(models.UserInfo, UserInfoAdmin)

 

 

5 list_select_related,列表時,連表查詢是否自動 select_related

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 就像在學習之前先要識字,我想在介紹優化 JavaScript 代碼之前,先介紹一下自己對編程語言的理解。故事要從一隻叫做 Theseus 的機械鼠和其發明人克勞德-香農(Claude Shannon)說起。在傳記《A Mind at Play:How Claude Shannon Invented ... ...
  • 在 《基於 vite 創建 vue3 全家桶》一文整合了 *Element Plus*,並將 *Element Plus* 中提供的圖標進行全局註冊,這樣可以很方便的延續 *Element UI* 的風格 —— 通過 *el-icon-xxx* 的方式使用圖標(如果有問題的朋友可以先閱讀前面的文章:... ...
  • 一:創建一個新的工程,項目初始化 npm init -y 二:搭建項目框架 三:編寫main.js文件內容,在index.js中引入,在把index.js引入到index.html中 例: export default()=>{ function computer(){ let h2=documen ...
  • 一、使用webpack優化前端性能方法 ⽤webpack優化前端性能是指優化webpack的輸出結果,讓打包的最終結果在瀏覽器運⾏快速⾼效。 可通過webpack優化前端的手段: 代碼壓縮(刪除多餘的代碼、註釋、簡化代碼的寫法等等⽅式) HTML文件代碼壓縮 使用HTMLWebpackPlugin插 ...
  • 內部類的基本使用 內部類概念 在一個類中定義一個類。舉例:在一個類A的內部定義一個類B,類B就被稱為內部類 我們把一個類放在另一個類的內部定義,稱為內部類(inner class)。 內部類的兩個要點: 內部類提供了更好的封裝。只能讓外部類直接訪問,不允許同一個包中的其他類直接訪問。 內部類可以直接 ...
  • 一、遞歸與迴圈的對比 遞歸會帶來大量的函數調用。這是不好的 在計算環節特別大的前提下,遞歸就是不好的,因為遞歸是先調用,再計算。 在大量計算的前提下可能會造成棧溢出(StackOverFlow) 如下圖: 迴圈是先計算再調用,計算完後會調用的方法會從棧中抹去,最後將結果輸出 能不用遞歸就不用遞歸 小 ...
  • 項目地址: GitHub - apache/skywalking-swck: Apache SkyWalking Cloud on Kubernetes 項目簡介: A bridge project between Apache SkyWalking and Kubernetes. SWCK is ...
  • 變數: 什麼是變數?一個可以存儲數據(存儲的地方在記憶體中),並可以在代碼的運行中,給與數據的改變 註意:變數的聲明必須在最前面 語法:數據類型 變數名稱 = 值; 案例: %d - 輸出一個整數 %.2f - 輸出一個小數(2代表的是小數位,可以改變) %c - 輸出一個字元 %s - 輸出一個字元 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...