Django 從 0 到 1 打造完整電商平臺:使用 Django 消息框架與用戶權(quán)限初步

使用 Django 消息框架與用戶權(quán)限初步

IT策士 10余年一線大廠經(jīng)驗,專注 IT 思維、架構(gòu)、職場進階。我會在公眾號、今日頭條持續(xù)發(fā)布最新文章,助你少走彎路。


大家好,我是IT策士。從第 6 篇到第 9 篇,我們密集地完成了用戶注冊、登錄、個人中心、地址管理等模塊,用戶體系已經(jīng)相當(dāng)完善。但在實際開發(fā)中,你還會遇到兩類問題:一是如何優(yōu)雅地給用戶操作反饋(成功提示、錯誤警告);二是如何對不同角色的用戶做訪問控制(比如普通用戶不能進入 Admin 后臺)。今天我們就用一篇“收尾 + 進階”的內(nèi)容,徹底解決這兩件事——Django 消息框架用戶權(quán)限系統(tǒng)。

雖然前幾篇我們已經(jīng)零零散散用過 messages.success(),但從未系統(tǒng)講解它的原理和高級用法;權(quán)限方面也僅用了 login_required,而 Django 內(nèi)置的權(quán)限體系遠(yuǎn)比這個強大。掌握它們,后續(xù)開發(fā)商品、訂單模塊時會更加游刃有余。


一、Django 消息框架深入

1.1 什么是消息框架?

Django 的消息框架(django.contrib.messages)提供了一種跨請求傳遞消息的機制。你在視圖里調(diào)用 messages.success(request, '操作成功'),用戶刷新或跳轉(zhuǎn)到下一個頁面時,就能看到這條消息。它特別適合“操作后給出反饋”的場景:注冊成功、密碼錯誤、地址刪除等。

消息框架的核心特點:

  • 存儲在 session / cookie 中,一次讀取后自動清除。

  • 支持多種級別:DEBUG、INFOSUCCESS、WARNING、ERROR

  • 可以在模板中統(tǒng)一渲染,結(jié)合 Bootstrap 的 alert 組件效果極佳。

1.2 配置確認(rèn)

Django 默認(rèn)已經(jīng)啟用了消息框架,settings.py 中的 INSTALLED_APPS 包含 'django.contrib.messages',MIDDLEWARE 包含 'django.contrib.messages.middleware.MessageMiddleware'TEMPLATEScontext_processors 包含 'django.contrib.messages.context_processors.messages'。我們無需額外配置,直接用。

1.3 消息級別與 Bootstrap 的對應(yīng)關(guān)系

Django 的消息級別常量(messages.DEBUG 等)輸出到模板時會轉(zhuǎn)換為小寫標(biāo)簽(debuginfo、success、warning、error)。Bootstrap 5 的 alert 類名恰好也是 alert-success、alert-warning 等。所以我們在 base.html 里可以這樣渲染:

{% if messages %}
    {% for message in messages %}
        <div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
            {{ message }}
            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
        </div>
    {% endfor %}
{% endif %}

這段代碼已在第 5 篇的 base.html 中存在,現(xiàn)在你理解它的由來了。message.tags 會根據(jù)級別輸出 success、warning 等字符串。

1.4 常用 API

在視圖中導(dǎo)入并使用:

from django.contrib import messages

# 添加普通消息
messages.success(request, '注冊成功!')
messages.error(request, '賬號或密碼錯誤。')
messages.warning(request, '您的郵箱尚未激活。')
messages.info(request, '您的訂單正在處理中。')

# 添加可攜帶額外標(biāo)簽的消息(如給 Bootstrap 加類名)
messages.success(request, '操作成功', extra_tags='bg-success text-white')

extra_tags 會附加到 message.tags 中,你可以用它定制特定消息的樣式。

1.5 實戰(zhàn)示例:登錄視圖中細(xì)化消息

我們已在登錄視圖里用過 messages.errormessages.success。現(xiàn)在可以加入 messages.warning 來提示未激活郵箱的用戶:

apps/users/views.pyuser_login 中找到 if user.is_active: 塊,在此之前插入郵箱激活檢查:

# 在 authenticate 成功后
if not user.email_active:
    messages.warning(request, '您的郵箱尚未激活,部分功能受限。')

這樣當(dāng)用戶登錄時,如果郵箱未激活,就能看到一條黃色警告。

1.6 消息框架的存儲后端

默認(rèn)存儲后端是 django.contrib.messages.storage.session.SessionStorage,消息存在 session 中。另一個可選后端是 CookieStorage,將消息存在 cookie 中(數(shù)據(jù)量小,無需 session)。切換方式在 settings.py 中添加:

MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'

我們的項目保持默認(rèn) session 后端即可,因為已經(jīng)用了大量 session(如短信驗證碼)。


二、用戶權(quán)限系統(tǒng)初步

Django 自帶了一套強大的權(quán)限系統(tǒng),核心概念包括:

  • User:用戶

  • Group:用戶組(管理員組、運營組等)

  • Permission:權(quán)限(可以細(xì)分到每個模型的增刪改查)

電商項目中,我們至少需要:

  • 普通用戶:只能瀏覽商品、管理自己的購物車和訂單。

  • 管理員(staff/superuser):可以登錄 Admin 后臺,管理全站。

2.1 查看內(nèi)置權(quán)限

dbshell 中可以查看:

python manage.py dbshell
sqlite> .headers on
sqlite> SELECT * FROM auth_permission;

你會看到 Django 為每個模型自動生成了 add、change、delete、view 四種權(quán)限。例如 users | user | Can add user、products | sku | Can change sku 等。

2.2 創(chuàng)建用戶組和分配權(quán)限(Admin 操作)

  1. 登錄 http://127.0.0.1:8000/admin/

  2. 點擊“組” → “增加組”

  3. 組名輸入 運營人員,在權(quán)限選擇框中,勾選 products | sku | Can change sku、products | sku | Can view sku 等與商品管理相關(guān)的權(quán)限,保存。

  4. 回到用戶列表,編輯一個普通用戶,將其添加到 運營人員 組,勾選 Staff status 但不勾選 Superuser status。這樣該用戶就能登錄 Admin 后臺,但只能看到和管理商品相關(guān)的內(nèi)容。

2.3 在視圖中使用權(quán)限檢查

Django 提供了多種檢查權(quán)限的方式:

方式一:裝飾器 @permission_required

from django.contrib.auth.decorators import permission_required

@permission_required('products.view_sku', raise_exception=True)
def some_view(request):
    ...

raise_exception=True 會返回 403 禁止訪問頁面(需要創(chuàng)建 403.html 模板),適合 API 或?qū)Π踩蟾叩牡胤健?/span>

方式二:User.has_perm() 在視圖邏輯中判斷

def manage_product(request):
    if not request.user.has_perm('products.change_sku'):
        messages.error(request, '你沒有權(quán)限修改商品信息。')
        return redirect('home')
    # ... 有權(quán)限的操作

方式三:模板中判斷權(quán)限

{% if perms.products.add_sku %}
    <a href="{% url 'admin:products_sku_add' %}" class="btn btn-success">新增商品</a>
{% endif %}

模板全局變量 perms 可以在任何模板中使用,它是 django.contrib.auth.context_processors.auth 提供的。

2.4 保護 Admin 入口

目前任何登錄用戶點擊“后臺管理”都能進入 Admin(雖然只能看到無權(quán)限的界面),我們可以在導(dǎo)航欄里根據(jù) user.is_staff 來控制顯示:

修改 templates/base.html 導(dǎo)航欄下拉菜單部分:

{% if user.is_authenticated %}
    ...
    {% if user.is_staff %}
        <li><a class="dropdown-item" href="{% url 'admin:index' %}">后臺管理</a></li>
    {% endif %}
    <li><a class="dropdown-item" href="{% url 'users:logout' %}">退出登錄</a></li>
{% endif %}

這樣只有 is_staff=True 的用戶(管理員或運營人員)才會看到后臺入口。

2.5 創(chuàng)建自定義權(quán)限(可選)

如果覺得 Django 自動生成的四類權(quán)限不夠精細(xì),可以在模型的 Meta 里定義自定義權(quán)限。例如,在 orders/models.pyOrder 模型 Meta 中添加:

class Meta:
    ...
    permissions = [
        ('can_export_orders', '可以導(dǎo)出訂單'),
        ('can_view_report', '可以查看報表'),
    ]

然后執(zhí)行 makemigrationsmigrate,新權(quán)限就會寫入 auth_permission 表。之后可以用 @permission_required('orders.can_export_orders') 進行保護。


三、實戰(zhàn):結(jié)合消息框架和權(quán)限,優(yōu)化個人中心

我們在個人中心側(cè)邊欄增加一個入口,僅對有商品管理權(quán)限的用戶顯示“商品管理”鏈接。

打開 apps/users/templates/users/center.html,在側(cè)邊欄的 ul 中,添加:

{% if perms.products.view_sku %}
    <li class="list-group-item">
        <a href="{% url 'admin:index' %}" class="text-decoration-none">商品管理</a>
    </li>
{% endif %}

同時在視圖中(personal_center)無需額外處理,模板變量 perms 自動可用。

為了演示權(quán)限不足時的反饋,我們新建一個測試視圖(臨時放在 apps/users/views.py):

@login_required(login_url='users:login')
@permission_required('products.add_spu', raise_exception=False, login_url='users:center')
def test_permission(request):
    messages.info(request, '你有添加 SPU 的權(quán)限,歡迎進入。')
    return render(request, 'users/permission_test.html')

若用戶沒有該權(quán)限,會重定向到 users:center,我們在重定向前可以使用 messages.warning 提示嗎?由于 permission_required 直接重定向,無法在重定向時插入消息。但我們可以通過自定義視圖自行處理:

def test_permission(request):
    if not request.user.has_perm('products.add_spu'):
        messages.warning(request, '你沒有添加商品的權(quán)限。')
        return redirect('users:center')
    messages.info(request, '你有添加 SPU 的權(quán)限,歡迎進入。')
    return render(request, 'users/permission_test.html')

這樣更靈活,且能帶上消息反饋。這是權(quán)限 + 消息框架的典型組合。


四、測試與輸出示例

啟動服務(wù)器:

python manage.py runserver

測試 1:消息樣式展示

  • 故意登錄失敗,提示“賬號或密碼錯誤”,應(yīng)為紅色 alert-danger。

  • 注冊成功提示為綠色 alert-success

  • 郵箱未激活登錄時提示黃色 alert-warning(根據(jù)前面添加的警告)。

控制臺顯示狀態(tài)碼 200 或 302,前端消息自動消失或手動關(guān)閉。

測試 2:權(quán)限控制

  • 用超級管理員登錄,導(dǎo)航欄出現(xiàn)“后臺管理”。

  • 用一個普通用戶(is_staff=False)登錄,導(dǎo)航欄不顯示“后臺管理”。

  • 普通用戶嘗試直接訪問 /admin/ 會被重定向到登錄頁(Admin 自帶的權(quán)限檢查)。

  • 訪問自定義的 test_permission 頁面(需要提前綁定路由)看到“你沒有添加商品的權(quán)限”并重定向到個人中心。

控制臺輸出示例(權(quán)限不足):

[22/May/2026 11:20:10] "GET /users/test_permission/ HTTP/1.1" 302 0
[22/May/2026 11:20:10] "GET /users/center/ HTTP/1.1" 200 3654

五、總結(jié)與下集預(yù)告

今天,我們完成了用戶模塊的最后兩塊拼圖:

  • 消息框架:系統(tǒng)講解了級別、存儲、模板渲染,并與 Bootstrap 完美融合,讓用戶反饋更友好。

  • 權(quán)限系統(tǒng):從內(nèi)置權(quán)限、用戶組、is_staff 到自定義權(quán)限,再到視圖與模板中的權(quán)限判斷,形成了初步的訪問控制體系。

至此,用戶模塊全線竣工!從下一篇開始,我們將正式進入商品模塊。第 11 篇,我會深入講解 商品分類與 SPU/SKU 設(shè)計,結(jié)合電商業(yè)務(wù)場景,把多級分類的樹形展示和商品規(guī)格管理做得更完善,為商品列表和詳情打下堅實基礎(chǔ)。繼續(xù)保持節(jié)奏,我們明天見!

想了解更多還可以去公眾號、今日頭條搜索「IT策士」,一起升級 IT 思維 !


本文為《Django 從 0 到 1 打造完整電商平臺》系列第 10 篇,作者:IT策士,未經(jīng)授權(quán)禁止轉(zhuǎn)載。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容