使用 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.messagesMIDDLEWARE包含django.contrib.messages.middleware.MessageMiddlewareTEMPLATES的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里可以这样渲染{%ifmessages %}{%formessageinmessages %}divclassalert alert-{{ message.tags }} alert-dismissible fade showrolealert{{message}}buttontypebuttonclassbtn-close>alertaria-labelClose/button/div{% endfor %}{% endif %}这段代码已在第 5 篇的base.html中存在现在你理解它的由来了。message.tags会根据级别输出success、warning等字符串。1.4 常用 API在视图中导入并使用from django.contribimportmessages# 添加普通消息messages.success(request,注册成功)messages.error(request,账号或密码错误。)messages.warning(request,您的邮箱尚未激活。)messages.info(request,您的订单正在处理中。)# 添加可携带额外标签的消息如给 Bootstrap 加类名messages.success(request,操作成功,extra_tagsbg-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:块在此之前插入邮箱激活检查# 在 authenticate 成功后ifnot user.email_active: messages.warning(request,您的邮箱尚未激活部分功能受限。)这样当用户登录时如果邮箱未激活就能看到一条黄色警告。1.6 消息框架的存储后端默认存储后端是django.contrib.messages.storage.session.SessionStorage消息存在 session 中。另一个可选后端是CookieStorage将消息存在 cookie 中数据量小无需 session。切换方式在settings.py中添加MESSAGE_STORAGEdjango.contrib.messages.storage.cookie.CookieStorage我们的项目保持默认 session 后端即可因为已经用了大量 session如短信验证码。二、用户权限系统初步Django 自带了一套强大的权限系统核心概念包括User用户Group用户组管理员组、运营组等Permission权限可以细分到每个模型的增删改查电商项目中我们至少需要普通用户只能浏览商品、管理自己的购物车和订单。管理员staff/superuser可以登录 Admin 后台管理全站。2.1 查看内置权限在dbshell中可以查看python manage.py dbshell sqlite.headers on sqliteSELECT * 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_requiredfrom django.contrib.auth.decoratorsimportpermission_required permission_required(products.view_sku,raise_exceptionTrue)def some_view(request):...raise_exceptionTrue会返回 403 禁止访问页面需要创建 403.html 模板适合 API 或对安全要求高的地方。方式二User.has_perm()在视图逻辑中判断def manage_product(request):ifnot request.user.has_perm(products.change_sku): messages.error(request,你没有权限修改商品信息。)returnredirect(home)# ... 有权限的操作方式三模板中判断权限{%ifperms.products.add_sku %}ahref{% url admin:products_sku_add %}classbtn btn-success新增商品/a{% endif %}模板全局变量perms可以在任何模板中使用它是django.contrib.auth.context_processors.auth提供的。2.4 保护 Admin 入口目前任何登录用户点击“后台管理”都能进入 Admin虽然只能看到无权限的界面我们可以在导航栏里根据user.is_staff来控制显示修改templates/base.html导航栏下拉菜单部分{%ifuser.is_authenticated %}...{%ifuser.is_staff %}liaclassdropdown-itemhref{% url admin:index %}后台管理/a/li{% endif %}liaclassdropdown-itemhref{% url users:logout %}退出登录/a/li{% endif %}这样只有is_staffTrue的用户管理员或运营人员才会看到后台入口。2.5 创建自定义权限可选如果觉得 Django 自动生成的四类权限不够精细可以在模型的Meta里定义自定义权限。例如在orders/models.py的Order模型 Meta 中添加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中添加{%ifperms.products.view_sku %}liclasslist-group-itemahref{% url admin:index %}classtext-decoration-none商品管理/a/li{% endif %}同时在视图中personal_center无需额外处理模板变量perms自动可用。为了演示权限不足时的反馈我们新建一个测试视图临时放在apps/users/views.pylogin_required(login_urlusers:login)permission_required(products.add_spu,raise_exceptionFalse,login_urlusers:center)def test_permission(request): messages.info(request,你有添加 SPU 的权限欢迎进入。)returnrender(request,users/permission_test.html)若用户没有该权限会重定向到users:center我们在重定向前可以使用messages.warning提示吗由于permission_required直接重定向无法在重定向时插入消息。但我们可以通过自定义视图自行处理def test_permission(request):ifnot request.user.has_perm(products.add_spu): messages.warning(request,你没有添加商品的权限。)returnredirect(users:center)messages.info(request,你有添加 SPU 的权限欢迎进入。)returnrender(request,users/permission_test.html)这样更灵活且能带上消息反馈。这是权限 消息框架的典型组合。四、测试与输出示例启动服务器python manage.py runserver测试 1消息样式展示故意登录失败提示“账号或密码错误”应为红色alert-danger。注册成功提示为绿色alert-success。邮箱未激活登录时提示黄色alert-warning根据前面添加的警告。控制台显示状态码 200 或 302前端消息自动消失或手动关闭。测试 2权限控制用超级管理员登录导航栏出现“后台管理”。用一个普通用户is_staffFalse登录导航栏不显示“后台管理”。普通用户尝试直接访问/admin/会被重定向到登录页Admin 自带的权限检查。访问自定义的test_permission页面需要提前绑定路由看到“你没有添加商品的权限”并重定向到个人中心。控制台输出示例权限不足[22/May/202611:20:10]GET /users/test_permission/ HTTP/1.13020[22/May/202611:20:10]GET /users/center/ HTTP/1.12003654五、总结与下集预告今天我们完成了用户模块的最后两块拼图消息框架系统讲解了级别、存储、模板渲染并与 Bootstrap 完美融合让用户反馈更友好。权限系统从内置权限、用户组、is_staff到自定义权限再到视图与模板中的权限判断形成了初步的访问控制体系。至此用户模块全线竣工从下一篇开始我们将正式进入商品模块。第 11 篇我会深入讲解商品分类与 SPU/SKU 设计结合电商业务场景把多级分类的树形展示和商品规格管理做得更完善为商品列表和详情打下坚实基础。想了解更多还可以去其它平台搜索「IT策士」一起升级 IT 思维 本文为《Django 从 0 到 1 打造完整电商平台》系列第 10 篇作者IT策士未经授权禁止转载。