Django项目动态角色菜单权限场景数据库设计最佳实践咨询
权限模型方案评估与优化建议
方案1可行性结论
- 方案1完全可以满足你提出的所有需求
- 适配权限查询接口:通过用户关联的角色ID,直接过滤
RoleMenuRight表即可拿到该角色所有绑定菜单的操作权限,关联DashboardMenu表取菜单属性后,可直接映射为你要求的返回结构,查询性能优异 - 适配权限配置接口:收到入参后,先删除指定角色ID的所有
RoleMenuRight旧记录,再批量插入入参中menus数组的每条配置即可,逻辑简单直观
- 适配权限查询接口:通过用户关联的角色ID,直接过滤
- 方案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
相关产品推荐
相关产品推荐

