【后端】【Django DRF】从零实现RBAC 权限管理系统

Django DRF 实现 RBAC 权限管理系统

在 Web 应用中,权限管理 是一个核心功能,尤其是在多用户系统中,需要精细化控制不同用户的访问权限。本文介绍如何使用 Django + DRF 设计并实现 RBAC(基于角色的访问控制)系统,支持 目录、菜单、按钮权限


1. RBAC 体系结构设计

RBAC 主要包含以下核心概念:

  1. 用户(User):系统中的使用者。
  2. 角色(Role):用于分组用户,每个角色拥有不同的权限。
  3. 权限(Permission):控制用户可以访问的资源,分为:
    • 目录(directory):仅用于分组,不可直接访问。
    • 菜单(menu):可点击,通常对应一个页面。
    • 按钮(button):更细粒度的操作权限,如“新增”、“编辑”按钮。

2. 数据模型设计

用户模型

继承 Django 的 AbstractUser,支持多角色:

from django.db import models
from django.contrib.auth.models import AbstractUserclass User(AbstractUser):roles = models.ManyToManyField("Role", blank=True, related_name="users")def __str__(self):return self.username

角色模型

每个角色可以关联多个权限:

class Role(models.Model):name = models.CharField(max_length=50, unique=True)permissions = models.ManyToManyField("Permission", blank=True, related_name="roles")def __str__(self):return self.name

权限模型

使用 type 字段区分 目录、菜单、按钮,并支持层级结构:

class Permission(models.Model):TYPE_CHOICES = [("directory", "目录"),("menu", "菜单"),("button", "按钮")]name = models.CharField(max_length=100, unique=True)code = models.CharField(max_length=100, unique=True)  # 唯一标识type = models.CharField(max_length=10, choices=TYPE_CHOICES, default="menu")parent = models.ForeignKey("self", null=True, blank=True, on_delete=models.CASCADE, related_name="children")def __str__(self):return self.name

3. 数据序列化

使用 Django Rest Framework (DRF) 创建序列化器:

from rest_framework import serializersclass PermissionSerializer(serializers.ModelSerializer):class Meta:model = Permissionfields = "__all__"class RoleSerializer(serializers.ModelSerializer):permissions = PermissionSerializer(many=True, read_only=True)class Meta:model = Rolefields = "__all__"class UserSerializer(serializers.ModelSerializer):roles = RoleSerializer(many=True, read_only=True)class Meta:model = Userfields = "__all__"

4. 视图层

使用 viewsets 处理 API 逻辑,提供 增删改查

from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticatedclass PermissionViewSet(viewsets.ModelViewSet):queryset = Permission.objects.all()serializer_class = PermissionSerializerpermission_classes = [IsAuthenticated]class RoleViewSet(viewsets.ModelViewSet):queryset = Role.objects.all()serializer_class = RoleSerializerpermission_classes = [IsAuthenticated]class UserViewSet(viewsets.ModelViewSet):queryset = User.objects.all()serializer_class = UserSerializerpermission_classes = [IsAuthenticated]

5. API 路由配置

使用 DefaultRouter 自动生成路由:

from rest_framework.routers import DefaultRouter
from django.urls import path, includerouter = DefaultRouter()
router.register(r'permissions', PermissionViewSet)
router.register(r'roles', RoleViewSet)
router.register(r'users', UserViewSet)urlpatterns = [path('api/', include(router.urls)),
]

6. RBAC 角色权限管理示例

假设系统有以下需求:

  1. 管理员角色:可管理用户、分配角色,拥有所有权限。
  2. 普通用户角色:仅能访问特定菜单,不可管理用户。
  3. 按钮权限:仅某些角色可执行“删除用户”等操作。

创建权限

Permission.objects.create(name="系统管理", code="sys_manage", type="directory")
Permission.objects.create(name="用户管理", code="user_manage", type="menu", parent_id=1)
Permission.objects.create(name="删除用户", code="btn_delete_user", type="button", parent_id=2)

创建角色并赋权

admin_role = Role.objects.create(name="管理员")
user_role = Role.objects.create(name="普通用户")admin_role.permissions.add(Permission.objects.get(code="sys_manage"))
user_role.permissions.add(Permission.objects.get(code="user_manage"))

创建用户并分配角色

admin = User.objects.create_user(username="admin", password="admin123")
user = User.objects.create_user(username="user", password="user123")admin.roles.add(admin_role)
user.roles.add(user_role)

7. 角色权限校验

用户登录后,前端可根据 菜单和按钮权限 动态渲染页面:

def get_user_permissions(user):permissions = Permission.objects.filter(roles__users=user).values_list("code", flat=True)return list(permissions)

示例:

get_user_permissions(admin)  
# 返回 ['sys_manage', 'user_manage', 'btn_delete_user']
get_user_permissions(user)  
# 返回 ['user_manage']

前端可据此 控制菜单显示、按钮禁用,实现精细化权限管理。


8. 设计优势

灵活性:支持 多级菜单、按钮权限控制,满足复杂权限需求。
可扩展性:未来可新增 API 级别权限、数据权限,无需大改结构。
高效查询:通过 ManyToManyForeignKey,高效检索用户权限。
前后端兼容:前端可基于权限数据 动态渲染 UI,隐藏无权限功能。


9. 总结

本文基于 Django DRF 设计了 RBAC 角色权限管理系统,实现了:

  1. 目录、菜单、按钮 权限层级。
  2. 用户 - 角色 - 权限 关联设计。
  3. 序列化、视图、API 路由 处理。
  4. 角色分配、权限校验 方法。
  5. 前端动态权限控制 支持。

这种 基于 RBAC 的权限管理 适用于大多数 企业级管理系统,在 权限控制、扩展性、查询效率 方面均表现优越!🚀

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/74607.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#基础学习(五)函数中的ref和out

1. 引言:为什么需要ref和out? ​问题背景:函数参数默认按值传递,值类型在函数内修改不影响外部变量;引用类型重新赋值时外部对象不变。​核心作用:允许函数内部修改外部变量的值,实现“双向传参…

八纲辨证总则

一、八纲辨证的核心定义 八纲即阴、阳、表、里、寒、热、虚、实,是中医分析疾病共性的纲领性辨证方法。 作用:通过八类证候归纳疾病本质,为所有辨证方法(如脏腑辨证、六经辨证)的基础。 二、八纲分类与对应关系 1. 总…

【linux重设gitee账号密码 克隆私有仓库报错】

出现问题时 Cloning into xxx... remote: [session-1f4b16a4] Unauthorized fatal: Authentication failed for https://gitee.com/xxx/xxx.git/解决方案 先打开~/.git-credentials vim ~/.git-credentials或者创建一个 torch ~/.git-credentials 添加授权信息 username/pa…

绿联NAS安装内网穿透实现无公网IP也能用手机平板远程访问经验分享

文章目录 前言1. 开启ssh服务2. ssh连接3. 安装cpolar内网穿透4. 配置绿联NAS公网地址 前言 大家好,今天给大家带来一个超级炫酷的技能——如何在绿联NAS上快速安装cpolar内网穿透工具。想象一下,即使没有公网IP,你也能随时随地远程访问自己…

CSS 美化页面(一)

一、CSS概念 CSS(Cascading Style Sheets,层叠样式表)是一种用于描述 HTML 或 XML(如 SVG、XHTML)文档 样式 的样式表语言。它控制网页的 外观和布局,包括字体、颜色、间距、背景、动画等视觉效果。 二、CS…

空转 | GetAssayData doesn‘t work for multiple layers in v5 assay.

问题分析 当我分析多个样本的时候,而我的seurat又是v5时,通常就会出现这样的报错。 错误的原因有两个: 一个是参数名有slot变成layer 一个是GetAssayData 不是自动合并多个layers,而是选择保留。 那么如果我们想合并多个样本&…

UE4学习笔记 FPS游戏制作17 让机器人持枪 销毁机器人时也销毁机器人的枪 让机器人射击

添加武器插槽 打开机器人的Idle动画,方便查看武器位置 在动画面板里打开骨骼树,找到右手的武器节点,右键添加一个插槽,重命名为RightWeapon,右键插槽,添加一个预览资产,选择Rifle,根…

【JavaScript】七、函数

文章目录 1、函数的声明与调用2、形参默认值3、函数的返回值4、变量的作用域5、变量的访问原则6、匿名函数6.1 函数表达式6.2 立即执行函数 7、练习8、逻辑中断9、转为布尔型 1、函数的声明与调用 function 函数名(形参列表) {函数体 }eg: // 声明 function sayHi…

硬件基础--05_电压

电压(电势差) 有了电压,电子才能持续且定向移动起来,所有电压是形成电流的必要条件。 电压越大,能“定向移动”起来的电子就越多,电流就会越大。 有电压的同时,形成闭合回路才会有电流,不是有电压就有电流…

ES数据过多,索引拆分

公司企微聊天数据存储在 ES 中,虽然按照企业分储在不同的ES 索引中,但某些常用的企微主体使用量还是很大。4年中一个索引存储数据已经达到46多亿条数据,占用存储3.1tb, ES 配置 由于多一个副本,存储得翻倍,成本考虑…

存储服务器是指什么

今天小编主要来为大家介绍存储服务器主要是指什么,存储服务器与传统的物理服务器和云服务器是不同的,其是为了特定的目标所设计的,在硬件配置方式上也有着一定的区别,存储空间会根据需求的不同而改变。 存储服务器中一般会配备大容…

golang不使用锁的情况下,对slice执行并发写操作,是否会有并发问题呢?

背景 并发问题最简单的解决方案加个锁,但是,加锁就会有资源争用,提高并发能力其中的一个优化方向就是减少锁的使用。 我在之前的这篇文章《开启多个协程,并行对struct中的每个元素操作,是否会引起并发问题?》中讨论过多协程场景下struct的并发问题。 Go语言中的slice在…

Java知识整理round1

一、常见集合篇 1. 为什么数组索引从0开始呢?假如从1开始不行咩 数组(Array):一种用连续的内存空间存储相同数据类型数据的线性数据结构 (1)在根据数组索引获取元素的时候,会用索引和寻址公式…

【C++指针】搭建起程序与内存深度交互的桥梁(下)

🔥🔥 个人主页 点击🔥🔥 每文一诗 💪🏼 往者不可谏,来者犹可追——《论语微子篇》 译文:过去的事情已经无法挽回,未来的岁月还可以迎头赶上。 目录 C内存模型 new与…

JavaScript创建对象的多种方式

在JavaScript中,创建对象有多种方式,每种方式都有其优缺点。本文将介绍四种常见的对象创建模式:工厂模式、构造函数模式、原型模式和组合模式,并分析它们的特点以及如何优化。 1. 工厂模式 工厂模式是一种简单的对象创建方式&am…

muduo库的思路梳理

前言 对于muduo库源码的剖析我发现还是有些混乱的,所以这里再次梳理一下muduo网络库争取可以简单明了 首先对于muduo库来说,不能想的得太过于复杂,它无非就是一个线程池加上epoll组成的网络库 这里我们从用的角度出发理解muoduo网络库 #inc…

Keil5 安装全攻略

Keil5 安装全攻略 Keil5 是一款广泛用于嵌入式开发的 IDE,支持多种微控制器架构(如 ARM、C51)。本文将详细介绍 Keil5 的安装步骤、常见问题及解决方法,帮助您快速上手。 1. 安装前的准备工作 (1) 系统要求 操作系统&#xff1…

C语言do...while语句将数字反转后输出

一、题目引入 输入一个数字,将各位数字反转后输出? 参考代码: 二、分析代码 接着图片中的分析 第一 ->a 的值变为12 第二 ->进入while循环条件,a为12不等于0循环才停止(a的值为12,显然不等于0) 所以继续进行循环 第三 ->此时b的值为12取各位上的数字(即2) 打印…

优选算法系列(前缀和 _下) k

目录 五:和为 k 的子数组(medium) 题目链接:560. 和为 K 的子数组 - 力扣(LeetCode) 解法: 代码: 六:和可被 K 整除的子数组(medium) 题目链…

mac m3 pro 部署 stable diffusion webui

什么是Stable Diffusion WebUI ? Stable Diffusion WebUI 是一个基于Stable Diffusion模型开发的图形用户界面(GUI)工具。通过这个工具,我们可以很方便的基于提示词,描述一段文本来指导模型生成相应的图像。相比较通过…