使用 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、INFO、SUCCESS、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',TEMPLATES 的 context_processors 包含 'django.contrib.messages.context_processors.messages'。我們無需額外配置,直接用。
1.3 消息級別與 Bootstrap 的對應(yīng)關(guān)系
Django 的消息級別常量(messages.DEBUG 等)輸出到模板時會轉(zhuǎn)換為小寫標(biāo)簽(debug、info、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.error 和 messages.success。現(xiàn)在可以加入 messages.warning 來提示未激活郵箱的用戶:
在 apps/users/views.py 的 user_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 操作)
登錄
http://127.0.0.1:8000/admin/點擊“組” → “增加組”
組名輸入
運營人員,在權(quán)限選擇框中,勾選products | sku | Can change sku、products | sku | Can view sku等與商品管理相關(guān)的權(quán)限,保存。回到用戶列表,編輯一個普通用戶,將其添加到
運營人員組,勾選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.py 的 Order 模型 Meta 中添加:
class Meta:
...
permissions = [
('can_export_orders', '可以導(dǎo)出訂單'),
('can_view_report', '可以查看報表'),
]然后執(zhí)行 makemigrations 和 migrate,新權(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)載。