使用 Django 消息框架与用户权限初步
IT策士 10余年一线大厂经验,专注 IT 思维、架构、职场进阶。我也会在其它平台条持续发布最新文章,助你少走弯路。
从第 6 篇到第 9 篇,我们密集地完成了用户注册、登录、个人中心、地址管理等模块,用户体系已经相当完善。但在实际开发中,你还会遇到两类问题:一是如何优雅地给用户操作反馈(成功提示、错误警告);二是如何对不同角色的用户做访问控制(比如普通用户不能进入 Admin 后台)。今天我们就用一篇"收尾 + 进阶"的内容,彻底解决这两件事------Django 消息框架 和 用户权限系统。
虽然前几篇我们已经零零散散用过 messages.success(),但从未系统讲解它的原理和高级用法;权限方面也仅用了 login_required,而 Django 内置的权限体系远比这个强大。掌握它们,后续开发商品、订单模块时会更加游刃有余。
一、Django 消息框架深入
1.1 什么是消息框架?
Django 的消息框架(django.contrib.messages)提供了一种跨请求 传递消息的机制。你在视图里调用 messages.success(request, '操作成功'),用户刷新或跳转到下一个页面时,就能看到这条消息。它特别适合"操作后给出反馈"的场景:注册成功、密码错误、地址删除等。
消息框架的核心特点:
-
存储在 session / cookie 中,一次读取后自动清除。
-
支持多种级别:
DEBUG、INFO、SUCCESS、WARNING、ERROR。 -
可以在模板中统一渲染,结合 Bootstrap 的 alert 组件效果极佳。
1.2 配置确认
Django 默认已经启用了消息框架,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 的对应关系
Django 的消息级别常量(messages.DEBUG 等)输出到模板时会转换为小写标签(debug、info、success、warning、error)。Bootstrap 5 的 alert 类名恰好也是 alert-success、alert-warning 等。所以我们在 base.html 里可以这样渲染:
bash
{% 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 中存在,现在你理解它的由来了。message.tags 会根据级别输出 success、warning 等字符串。
1.4 常用 API
在视图中导入并使用:
bash
from django.contrib import messages
# 添加普通消息
messages.success(request, '注册成功!')
messages.error(request, '账号或密码错误。')
messages.warning(request, '您的邮箱尚未激活。')
messages.info(request, '您的订单正在处理中。')
# 添加可携带额外标签的消息(如给 Bootstrap 加类名)
messages.success(request, '操作成功', extra_tags='bg-success text-white')
extra_tags 会附加到 message.tags 中,你可以用它定制特定消息的样式。
1.5 实战示例:登录视图中细化消息
我们已在登录视图里用过 messages.error 和 messages.success。现在可以加入 messages.warning 来提示未激活邮箱的用户:
在 apps/users/views.py 的 user_login 中找到 if user.is_active: 块,在此之前插入邮箱激活检查:
bash
# 在 authenticate 成功后
if not user.email_active:
messages.warning(request, '您的邮箱尚未激活,部分功能受限。')
这样当用户登录时,如果邮箱未激活,就能看到一条黄色警告。
1.6 消息框架的存储后端
默认存储后端是 django.contrib.messages.storage.session.SessionStorage,消息存在 session 中。另一个可选后端是 CookieStorage,将消息存在 cookie 中(数据量小,无需 session)。切换方式在 settings.py 中添加:
bash
MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'
我们的项目保持默认 session 后端即可,因为已经用了大量 session(如短信验证码)。
二、用户权限系统初步
Django 自带了一套强大的权限系统,核心概念包括:
-
User:用户
-
Group:用户组(管理员组、运营组等)
-
Permission:权限(可以细分到每个模型的增删改查)
电商项目中,我们至少需要:
-
普通用户:只能浏览商品、管理自己的购物车和订单。
-
管理员(staff/superuser):可以登录 Admin 后台,管理全站。
2.1 查看内置权限
在 dbshell 中可以查看:
bash
python manage.py dbshell
sqlite> .headers on
sqlite> SELECT * FROM auth_permission;
你会看到 Django 为每个模型自动生成了 add、change、delete、view 四种权限。例如 users | user | Can add user、products | sku | Can change sku 等。
2.2 创建用户组和分配权限(Admin 操作)
-
登录
http://127.0.0.1:8000/admin/ -
点击"组" → "增加组"
-
组名输入
运营人员,在权限选择框中,勾选products | sku | Can change sku、products | sku | Can view sku等与商品管理相关的权限,保存。 -
回到用户列表,编辑一个普通用户,将其添加到
运营人员组,勾选Staff status但不勾选Superuser status。这样该用户就能登录 Admin 后台,但只能看到和管理商品相关的内容。
2.3 在视图中使用权限检查
Django 提供了多种检查权限的方式:
方式一:装饰器 @permission_required
bash
from django.contrib.auth.decorators import permission_required
@permission_required('products.view_sku', raise_exception=True)
def some_view(request):
...
raise_exception=True 会返回 403 禁止访问页面(需要创建 403.html 模板),适合 API 或对安全要求高的地方。
方式二:User.has_perm() 在视图逻辑中判断
bash
def manage_product(request):
if not request.user.has_perm('products.change_sku'):
messages.error(request, '你没有权限修改商品信息。')
return redirect('home')
# ... 有权限的操作
方式三:模板中判断权限
bash
{% 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(虽然只能看到无权限的界面),我们可以在导航栏里根据 user.is_staff 来控制显示:
修改 templates/base.html 导航栏下拉菜单部分:
bash
{% 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 创建自定义权限(可选)
如果觉得 Django 自动生成的四类权限不够精细,可以在模型的 Meta 里定义自定义权限。例如,在 orders/models.py 的 Order 模型 Meta 中添加:
bash
class Meta:
...
permissions = [
('can_export_orders', '可以导出订单'),
('can_view_report', '可以查看报表'),
]
然后执行 makemigrations 和 migrate,新权限就会写入 auth_permission 表。之后可以用 @permission_required('orders.can_export_orders') 进行保护。
三、实战:结合消息框架和权限,优化个人中心
我们在个人中心侧边栏增加一个入口,仅对有商品管理权限的用户显示"商品管理"链接。
打开 apps/users/templates/users/center.html,在侧边栏的 ul 中,添加:
bash
{% 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 自动可用。
为了演示权限不足时的反馈,我们新建一个测试视图(临时放在 apps/users/views.py):
bash
@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 的权限,欢迎进入。')
return render(request, 'users/permission_test.html')
若用户没有该权限,会重定向到 users:center,我们在重定向前可以使用 messages.warning 提示吗?由于 permission_required 直接重定向,无法在重定向时插入消息。但我们可以通过自定义视图自行处理:
bash
def test_permission(request):
if not request.user.has_perm('products.add_spu'):
messages.warning(request, '你没有添加商品的权限。')
return redirect('users:center')
messages.info(request, '你有添加 SPU 的权限,欢迎进入。')
return render(request, 'users/permission_test.html')
这样更灵活,且能带上消息反馈。这是权限 + 消息框架的典型组合。
四、测试与输出示例
启动服务器:
bash
python manage.py runserver
测试 1:消息样式展示
-
故意登录失败,提示"账号或密码错误",应为红色
alert-danger。 -
注册成功提示为绿色
alert-success。 -
邮箱未激活登录时提示黄色
alert-warning(根据前面添加的警告)。
控制台显示状态码 200 或 302,前端消息自动消失或手动关闭。
测试 2:权限控制
-
用超级管理员登录,导航栏出现"后台管理"。
-
用一个普通用户(
is_staff=False)登录,导航栏不显示"后台管理"。 -
普通用户尝试直接访问
/admin/会被重定向到登录页(Admin 自带的权限检查)。 -
访问自定义的
test_permission页面(需要提前绑定路由)看到"你没有添加商品的权限"并重定向到个人中心。
控制台输出示例(权限不足):
bash
[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
五、总结与下集预告
今天,我们完成了用户模块的最后两块拼图:
-
消息框架:系统讲解了级别、存储、模板渲染,并与 Bootstrap 完美融合,让用户反馈更友好。
-
权限系统 :从内置权限、用户组、
is_staff到自定义权限,再到视图与模板中的权限判断,形成了初步的访问控制体系。
至此,用户模块全线竣工!从下一篇开始,我们将正式进入商品模块。第 11 篇 ,我会深入讲解 商品分类与 SPU/SKU 设计,结合电商业务场景,把多级分类的树形展示和商品规格管理做得更完善,为商品列表和详情打下坚实基础。
想了解更多还可以去其它平台搜索「IT策士」,一起升级 IT 思维 !
本文为《Django 从 0 到 1 打造完整电商平台》系列第 10 篇,作者:IT策士,未经授权禁止转载。