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

Django项目动态角色菜单权限场景数据库设计最佳实践咨询

权限模型方案评估与优化建议

方案1可行性结论

  • 方案1完全可以满足你提出的所有需求
    • 适配权限查询接口:通过用户关联的角色ID,直接过滤RoleMenuRight表即可拿到该角色所有绑定菜单的操作权限,关联DashboardMenu表取菜单属性后,可直接映射为你要求的返回结构,查询性能优异
    • 适配权限配置接口:收到入参后,先删除指定角色ID的所有RoleMenuRight旧记录,再批量插入入参中menus数组的每条配置即可,逻辑简单直观
  • 方案1的局限性:
    • 存在字段冗余:部分不需要审批、导出等能力的菜单,can_approve、can_reject等字段永远为无效值,浪费存储空间
    • 扩展性差:后续新增操作类型时需要修改表结构加字段,维护成本高

更优的通用最佳实践

如果你的业务存在不同菜单支持的操作差异大、后续可能新增操作类型的情况,推荐用动态操作权限的方案,模型定义如下:

class User(models.Model):
    id = models.BigAutoField(primary_key=True)
    name = models.CharField(max_length=64)
    role = models.ForeignKey("Role", on_delete=models.PROTECT, db_column="role_id")

class DashboardMenu(models.Model):
    id = models.BigAutoField(primary_key=True)
    name = models.CharField(max_length=64)
    codename = models.CharField(max_length=64, unique=True)
    parent = models.ForeignKey("self", on_delete=models.CASCADE, null=True, db_column="parent_id")
    # 存储当前菜单支持的操作编码列表,如 ["view", "create", "approve"]
    supported_ops = models.JSONField(default=list)

class Role(models.Model):
    id = models.BigAutoField(primary_key=True)
    name = models.CharField(max_length=64, unique=True)
    desc = models.CharField(max_length=255, blank=True)

class RoleMenuPermission(models.Model):
    id = models.BigAutoField(primary_key=True)
    role = models.ForeignKey(Role, on_delete=models.CASCADE)
    menu = models.ForeignKey(DashboardMenu, on_delete=models.CASCADE)
    # 存储当前角色在该菜单下被授予的操作编码集合,如 ["view", "create"]
    granted_ops = models.JSONField(default=list)

    class Meta:
        # 保证一个角色在一个菜单下只有一条权限记录
        unique_together = ("role", "menu")

该方案的优势

  • 无冗余存储:不需要维护大量无效的bool字段,仅存储每个菜单实际支持的操作、每个角色实际被授予的操作
  • 扩展性极强:后续新增操作类型不需要修改表结构,仅需在对应菜单的supported_ops中新增操作编码即可
  • 完全适配现有接口需求:
    • 查询接口:拿到角色对应的RoleMenuPermission记录后,遍历菜单的supported_ops,判断每个操作编码是否在granted_ops中,即可生成你要求的user_can_xxx格式的返回值
    • 配置接口:收到入参后,把每个菜单下值为true的参数名去掉can_前缀(如can_create转为create),收集为granted_ops数组存储即可
  • 性能表现和方案1基本持平,JSON字段在MySQL 8.0+、PostgreSQL等主流数据库都有完善的性能优化支持

选型建议

如果你的业务操作类型固定(不超过10种)、后续几乎不会新增操作权限,直接用方案1即可,开发成本更低,维护更简单。如果业务迭代快、操作类型会不断新增,推荐使用上述优化方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 03:06:04