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

Django中按分支管理用户权限的最优方案咨询

Django按分支管理用户权限的最佳方案

针对你提出的「用户在不同分支拥有不同角色权限,且分支与角色组相互独立」的需求,最佳方案是通过扩展模型建立「用户-分支-角色」的关联关系,同时自定义分支维度的权限校验逻辑,避免为每个用户-分支组合重复创建组。

核心实现步骤

1. 定义基础模型

先创建分支模型,再通过中间表关联用户、分支和Django自带的Group(角色),同时可扩展额外属性(如邮件接收开关):

from django.db import models
from django.contrib.auth.models import User, Group

class Branch(models.Model):
    name = models.CharField(max_length=100, unique=True, verbose_name="分支名称")
    code = models.CharField(max_length=20, unique=True, verbose_name="分支编码")

    def __str__(self):
        return self.name

class UserBranchRole(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="branch_roles", verbose_name="用户")
    branch = models.ForeignKey(Branch, on_delete=models.CASCADE, verbose_name="所属分支")
    group = models.ForeignKey(Group, on_delete=models.CASCADE, verbose_name="角色组")
    receive_emails = models.BooleanField(default=True, verbose_name="接收分支员工邮件")

    class Meta:
        unique_together = ("user", "branch", "group")  # 避免重复绑定同一用户-分支-角色组合
        verbose_name = "用户分支角色"

2. 自定义分支权限校验函数

Django默认的user.has_perm()是全局权限校验,我们需要编写函数,结合用户在目标分支下的角色组来判断权限:

def has_branch_permission(user, perm_codename, branch):
    """
    校验用户在指定分支下是否拥有目标权限
    :param user: 当前用户对象
    :param perm_codename: 权限编码(如'change_employee')
    :param branch: 目标分支对象
    :return: bool,是否拥有权限
    """
    # 获取用户在该分支下的所有角色组ID
    user_group_ids = user.branch_roles.filter(branch=branch).values_list("group__id", flat=True)
    # 检查这些组是否包含目标权限
    return user.groups.filter(id__in=user_group_ids, permissions__codename=perm_codename).exists()

3. 视图中使用分支权限校验

在视图里,先获取当前操作的分支,再调用自定义函数校验权限:

from django.shortcuts import get_object_or_404
from django.http import HttpResponseForbidden
from .models import Branch
from .utils import has_branch_permission

def edit_employee(request, branch_code, employee_id):
    branch = get_object_or_404(Branch, code=branch_code)
    # 校验用户在该分支下是否有编辑员工的权限
    if not has_branch_permission(request.user, "change_employee", branch):
        return HttpResponseForbidden("无此分支的员工编辑权限")
    # 后续业务逻辑...

4. 模板中权限校验支持

通过自定义模板标签,让模板也能直接判断分支权限:

# 在app下创建templatetags/branch_perms.py
from django import template
from ..utils import has_branch_permission

register = template.Library()

@register.simple_tag
def has_branch_perm(user, perm_codename, branch):
    return has_branch_permission(user, perm_codename, branch)

模板中使用:

{% load branch_perms %}

{% if has_branch_perm request.user 'change_employee' current_branch %}
    <button type="button" class="btn btn-primary">编辑员工</button>
{% else %}
    <button type="button" class="btn btn-secondary" disabled>无编辑权限</button>
{% endif %}

5. 分支邮件接收控制

发送分支专属邮件时,通过UserBranchRole的receive_emails字段过滤用户:

from django.core.mail import send_mail
from .models import Branch

def send_branch_announcement(branch_code, subject, content):
    branch = get_object_or_404(Branch, code=branch_code)
    # 获取该分支下需要接收邮件的用户
    target_users = User.objects.filter(
        branch_roles__branch=branch,
        branch_roles__receive_emails=True
    ).distinct()
    # 批量发送邮件
    send_mail(
        subject=subject,
        message=content,
        from_email="admin@company.com",
        recipient_list=[user.email for user in target_users]
    )

6. 后台管理优化

通过Admin内联,让管理员可以直接在用户编辑页面分配不同分支的角色:

from django.contrib import admin
from django.contrib.auth.models import User
from .models import Branch, UserBranchRole

class UserBranchRoleInline(admin.TabularInline):
    model = UserBranchRole
    extra = 1

class CustomUserAdmin(admin.ModelAdmin):
    inlines = [UserBranchRoleInline]

# 替换默认的User Admin
admin.site.unregister(User)
admin.site.register(User, CustomUserAdmin)
admin.site.register(Branch)

方案优势

  • 分支与角色组完全解耦:同一角色(如HR Manager)可复用在任意分支,无需重复创建组
  • 权限粒度精确:可针对每个用户-分支-角色组合单独配置权限和附加属性
  • 扩展性强:后续可轻松添加分支级别的其他规则(如数据隔离、审批流程)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 12:05:20