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

Django音乐制作协作应用如何实现单项目动态角色权限控制

Django音乐项目协调应用项目级动态权限实现方案

核心设计思路

我们采用项目-角色-权限三级绑定架构实现需求,完全避免全局角色权限固化的问题:

  • 所有权限配置以单个项目为独立单元,同一角色名在不同项目可配置完全不同的权限集合
  • 同一用户在不同项目可分配不同角色,权限随项目自动切换
  • 支持项目内灵活增删角色、调整角色权限,无需修改代码即可适配所有业务场景

新增&改造模型定义

基于现有模型结构,只需新增2个权限相关模型,同时对JobPosition做少量字段扩展即可:

import uuid
from django.db import models
from django.conf import settings

# 项目级权限项表:预设所有可用的权限选项,全局统一维护
class ProjectPermission(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    codename = models.CharField(max_length=100, unique=True, help_text="权限标识,例如:view_budget、edit_event")
    name = models.CharField(max_length=100, help_text="权限展示名称,例如:查看预算、编辑活动")

# 项目自定义角色表:每个角色属于特定项目,权限独立配置
class ProjectRole(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    project = models.ForeignKey(JobProject, on_delete=models.CASCADE, related_name="custom_roles")
    name = models.CharField(max_length=50, help_text="角色名称,例如:鼓手、音响师、制片经理")
    permissions = models.ManyToManyField(ProjectPermission, blank=True, related_name="role_permissions")

    class Meta:
        unique_together = ('project', 'name') # 同一个项目内角色名唯一

对现有JobPosition模型新增用户、角色关联字段:

class JobPosition(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.ForeignKey(Title, on_delete=models.CASCADE)
    city = models.ForeignKey(City, on_delete=models.CASCADE)
    rate = models.CharField(max_length=20)
    jobproject = models.ForeignKey(JobProject, related_name='crew', on_delete=models.CASCADE, blank=True, null=True)
    # 新增关联字段
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="project_positions", help_text="担任该职位的用户")
    role = models.ForeignKey(ProjectRole, on_delete=models.SET_NULL, null=True, blank=True, help_text="该职位对应的项目内角色")

权限校验逻辑实现

通用权限校验函数

先实现基础校验方法,所有场景的权限判断都基于该函数:

def has_project_permission(user, project, permission_codename):
    """校验指定用户在指定项目下是否拥有指定权限"""
    if not user.is_authenticated:
        return False
    # 超级管理员直接放行
    if user.is_superuser:
        return True
    # 查询用户在该项目下所有职位关联的角色
    user_positions = JobPosition.objects.filter(user=user, jobproject=project).select_related('role')
    for position in user_positions:
        if position.role and position.role.permissions.filter(codename=permission_codename).exists():
            return True
    return False

后端接口权限控制

如果用DRF开发接口,自定义权限类即可:

from rest_framework.permissions import BasePermission

class ProjectLevelPermission(BasePermission):
    def has_permission(self, request, view):
        # 从路由/请求参数中获取当前项目ID
        project_id = view.kwargs.get('project_id') or request.query_params.get('project_id')
        if not project_id:
            return False
        try:
            project = JobProject.objects.get(id=project_id)
        except JobProject.DoesNotExist:
            return False
        # 从视图属性获取当前接口需要的权限
        required_perm = getattr(view, 'required_permission', None)
        if not required_perm:
            return False
        return has_project_permission(request.user, project, required_perm)

接口使用示例,比如预算查询接口要求view_budget权限:

class BudgetViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = dept_budget.objects.all()
    permission_classes = [ProjectLevelPermission]
    required_permission = 'view_budget' # 指定当前接口需要的权限

前端/模板展示控制

自定义模板标签实现页面元素的权限可见性控制:

from django import template
register = template.Library()

@register.simple_tag
def user_has_perm(user, project, perm_codename):
    return has_project_permission(user, project, perm_codename)

模板内使用示例:

{% load custom_tags %}
{% user_has_perm request.user current_project 'view_budget' as can_view_budget %}
{% if can_view_budget %}
    <!-- 仅有权限的用户可见预算模块 -->
    <div class="budget-section">{{ dept_budget.budget }}</div>
{% endif %}
<!-- 所有项目成员都能看到的活动信息,只要给所有角色配置view_event权限即可 -->
<div class="event-info">下一场录制地点:{{ next_event.location }}</div>

权限配置管理实现

实现对应的管理页面/接口即可满足灵活配置需求:

  • 项目创建后可在项目设置内新增/删除自定义角色,调整角色关联的权限
  • 给职位分配用户时,选择该项目下的对应角色,用户自动继承角色的所有权限
  • 如有单个用户临时权限的需求,可给JobPosition新增extra_permissions多对多字段关联ProjectPermission,校验时叠加该字段的权限即可

业务场景适配示例

完全匹配你提出的需求场景:

  • 给制片经理角色配置view_budget、view_event权限,可查看预算和活动信息
  • 给默认鼓手角色配置view_event权限,不配置view_budget,只能看活动信息
  • 若某项目需要给鼓手开放预算权限,直接在该项目的鼓手角色上新增view_budget权限即可,不会影响其他项目的鼓手权限

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 12:24:02