Django多应用如何实现全局认证与分角色权限管控?
实现方案
Django内置的Groups用户组机制完全可以覆盖这套需求,不需要调整全局认证配置,配合框架自带的认证、权限工具就能实现全部逻辑,具体做法如下:
1. 权限模型配置
直接用Django自带的django.contrib.auth.models.Group即可,不需要额外自定义权限模型。
首先在后台创建3个对应用模块的用户组:
- 个人支出管理访问组
- 待办清单访问组
- 邮件/报表调度器访问组
如果需要更细的权限标记,可以在对应应用的模型Meta类里加自定义权限,迁移后将权限绑定到对应用户组即可,示例:
# 个人支出应用的models.py from django.db import models class ExpensePermissionStub(models.Model): """仅用于注册自定义权限,不需要生成实际数据表""" class Meta: managed = False default_permissions = [] permissions = [ ("can_access_expense_module", "可访问个人支出管理模块"), ]
执行python manage.py makemigrations和python manage.py migrate后,进入后台把can_access_expense_module权限绑定到之前创建的个人支出管理访问组即可。另外两个模块用同样的方式配置对应权限和组的绑定关系。
管理员账号可以直接绑定所有组,也可以直接用内置的is_superuser/is_staff字段做管理员身份判断,超户默认拥有所有权限,不需要额外绑定组。后续给用户开哪个模块的权限,直接把用户加入对应组即可,不需要单独修改代码逻辑。
2. 页面访问逻辑实现
- 统一入口页设置为公共视图,不添加任何登录、权限校验,匿名用户和登录用户都能正常看到三个应用的入口卡片,符合需求。
- 用户点击应用入口时:
- 未登录用户自动跳转到登录页,登录成功后回跳到目标应用页面
- 已登录用户校验是否拥有对应模块的访问权限,有权限则正常进入,无权限则跳转到无权限提示页
视图层的权限校验直接用框架自带的工具即可,不需要手写判断逻辑:
from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.mixins import PermissionRequiredMixin from django.views.generic import TemplateView # 函数视图写法:个人支出模块首页 @login_required(login_url="/login/") @permission_required("expense.can_access_expense_module", raise_exception=False, login_url="/no-perm/") def expense_index(request): return render(request, "expense/index.html") # 类视图写法:调度器模块首页 class SchedulerIndexView(PermissionRequiredMixin, TemplateView): template_name = "scheduler/index.html" login_url = "/login/" permission_required = "scheduler.can_access_scheduler_module" permission_denied_url = "/no-perm/"
3. 管理员/普通用户差异化内容展示
分两层实现即可:
- 视图层:如果是数据层面的差异,比如普通用户只能看到自己创建的支出、待办数据,管理员能看到全量数据,直接在查询数据集时加判断即可:
def expense_list(request): if request.user.is_superuser: qs = Expense.objects.all() else: qs = Expense.objects.filter(created_by=request.user) return render(request, "expense/list.html", {"list": qs}) - 模板层:如果是页面元素的差异,比如管理员能看到删除按钮、全局配置入口,普通用户看不到,直接用模板自带的
request.user变量判断即可,不需要额外传上下文:<div class="toolbar"> <button>新增支出记录</button> {% if request.user.is_superuser %} <button>导出全量报表</button> <a href="/expense/rule-config/">报销规则配置</a> {% endif %} </div>
注意点
全局认证中间件保持默认配置即可,不需要修改,所有权限校验都在单个视图维度生效,不会影响公共入口的匿名访问。如果需要给个别用户临时开某个模块的权限,不需要加组,直接在后台给用户单独绑定对应权限即可,Django的权限校验会同时检查用户个人权限和所属组的权限,逻辑天然兼容。
内容的提问来源于stack exchange,提问作者Alex R.
相关产品推荐
相关产品推荐

