如何在Django中实现分部门的差异化角色权限控制?
Django角色权限实现指引(针对你的需求)
第一步:定义核心模型
先把部门、用户角色的关联逻辑落地,推荐用Django的AbstractUser扩展默认用户模型,不用额外关联表,操作更直观:
# models.py from django.contrib.auth.models import AbstractUser from django.db import models class Department(models.Model): name = models.CharField(max_length=50, unique=True) def __str__(self): return self.name class CustomUser(AbstractUser): ROLE_CHOICES = ( ('manager', 'Manager'), ('normal', 'Normal User'), ) role = models.CharField(max_length=10, choices=ROLE_CHOICES, default='normal') department = models.ForeignKey(Department, on_delete=models.SET_NULL, null=True, blank=True) # 快捷判断方法,视图和模板里用起来更方便 def is_manager(self): return self.role == 'manager'
然后在settings.py里指定自定义用户模型:
AUTH_USER_MODEL = '你的应用名.CustomUser'
第二步:迁移数据库
执行命令生成并应用数据库表:
python manage.py makemigrations python manage.py migrate
第三步:视图层面的权限控制
函数视图示例
给每个仪表盘视图加权限判断,管理员直接放行,普通用户仅能访问自身部门的页面:
# views.py from django.shortcuts import render from django.contrib.auth.decorators import login_required @login_required def finance_dashboard(request): if request.user.is_manager or request.user.department.name == '财务部': return render(request, 'finance_dashboard.html') return render(request, 'no_permission.html') @login_required def sales_dashboard(request): if request.user.is_manager or request.user.department.name == '销售部': return render(request, 'sales_dashboard.html') return render(request, 'no_permission.html') @login_required def admin_overview(request): if request.user.is_manager: return render(request, 'admin_overview.html') return render(request, 'no_permission.html')
类视图示例(封装权限逻辑)
用Mixin复用权限判断逻辑,避免重复代码:
from django.views.generic import TemplateView from django.contrib.auth.mixins import LoginRequiredMixin from django.shortcuts import render class DepartmentPermissionMixin(LoginRequiredMixin): required_department = None # 子类指定对应部门 def dispatch(self, request, *args, **kwargs): if not request.user.is_manager: if request.user.department.name != self.required_department: return render(request, 'no_permission.html') return super().dispatch(request, *args, **kwargs) class FinanceDashboardView(DepartmentPermissionMixin, TemplateView): template_name = 'finance_dashboard.html' required_department = '财务部' class SalesDashboardView(DepartmentPermissionMixin, TemplateView): template_name = 'sales_dashboard.html' required_department = '销售部'
第四步:模板层面的权限控制
在导航栏或入口列表里,根据用户角色和部门显示对应仪表盘入口:
<!-- base.html 导航栏片段 --> <ul> {% if user.is_manager %} <li><a href="{% url 'admin_overview' %}">总览仪表盘</a></li> {% endif %} {% if user.is_manager or user.department.name == '财务部' %} <li><a href="{% url 'finance_dashboard' %}">财务部仪表盘</a></li> {% endif %} {% if user.is_manager or user.department.name == '销售部' %} <li><a href="{% url 'sales_dashboard' %}">销售部仪表盘</a></li> {% endif %} {% if user.is_manager or user.department.name == '运营部' %} <li><a href="{% url 'operation_dashboard' %}">运营部仪表盘</a></li> {% endif %} </ul>
第五步:Django Admin后台配置
把自定义用户和部门模型注册到Admin,方便后台分配角色和部门:
# admin.py from django.contrib import admin from django.contrib.auth.admin import UserAdmin from .models import CustomUser, Department class CustomUserAdmin(UserAdmin): # 用户编辑页显示角色和部门字段 fieldsets = UserAdmin.fieldsets + ( ('自定义信息', {'fields': ('role', 'department')}), ) # 用户列表页显示角色和部门 list_display = UserAdmin.list_display + ('role', 'department') admin.site.register(CustomUser, CustomUserAdmin) admin.site.register(Department)
后台操作流程:
- 先创建三个部门(财务部、销售部、运营部)
- 添加用户时,给用户分配对应角色和部门
额外提示
- 若想用Django Group(组)管理角色,可把Manager设为一个组,给组分配全部门仪表盘权限;普通用户按部门分组。但你的需求用
role字段更直接,无需额外处理组权限。 - 权限判断尽量封装成方法或Mixin,后续修改角色逻辑只需调整一处即可。
- 可自定义无权限提示页,提升用户体验。
内容的提问来源于stack exchange,提问作者Sutefano18
相关产品推荐
相关产品推荐

