You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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)

后台操作流程:

  1. 先创建三个部门(财务部、销售部、运营部)
  2. 添加用户时,给用户分配对应角色和部门

额外提示

  • 若想用Django Group(组)管理角色,可把Manager设为一个组,给组分配全部门仪表盘权限;普通用户按部门分组。但你的需求用role字段更直接,无需额外处理组权限。
  • 权限判断尽量封装成方法或Mixin,后续修改角色逻辑只需调整一处即可。
  • 可自定义无权限提示页,提升用户体验。

内容的提问来源于stack exchange,提问作者Sutefano18

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 22:31:13