角色管理模块是后台系统权限控制的基础,基于角色分配权限可以有效管理用户访问范围与操作行为。通过细粒度划分角色,系统可兼顾灵活性与安全性,提升整体管理效率。
本文围绕 dvadmin/system/views/role.py
,解析角色的增删改查、菜单按钮权限配置与数据范围控制的实现方式。结合源码细节探讨模块设计特点、接口设计思路及其在权限管理中的作用。
文章目录
role.py
本系统采用 Django + DRF 构建后台管理平台,聚焦角色管理、权限分配、系统配置模块。dvadmin/system/views/role.py
文件负责处理角色的增删改查、数据权限设置、菜单按钮权限配置。角色作为权限体系的核心,通过角色关联用户、菜单、字段、按钮,形成系统的权限控制基石。模块基于标准 ViewSet 开发,支持扩展性强的自定义逻辑,便于适配复杂的业务权限需求。
项目特点 | 描述 |
---|---|
技术栈 | Django + DRF |
功能定位 | 后台管理系统角色模块,统一管理角色及其权限资源 |
设计原则 | 标准 RESTful,逻辑清晰,扩展性强 |
权限控制方式 | 基于角色的菜单、按钮、字段多维度权限分配 |
dvadmin/system/views/role.py
定义了角色管理模块的接口控制逻辑,包含角色的创建、查询、更新、删除,以及角色对应的菜单、按钮、字段权限的关联操作。模块通过重载父类方法,实现了角色数据权限动态调整(如绑定数据范围、部门权限),并提供专门接口处理角色授权、角色按钮权限配置。所有接口统一使用序列化器进行数据校验和格式化输出,保证数据一致性和接口规范性。
模块职责 | 说明 |
---|---|
角色基本信息管理 | 包括角色名称、标识、描述等属性的增删改查 |
菜单权限分配 | 为角色绑定对应菜单,实现功能模块的访问控制 |
按钮权限分配 | 精细控制角色对页面功能按钮的可见与可操作性 |
字段权限配置 | 细粒度控制角色对模型字段的可读可写权限 |
数据范围权限 | 定义角色可操作数据的范围,如本人、部门、全部、自定义 |
动态接口授权 | 接口化处理角色权限调整,支持前端权限管理页面无刷新操作 |
在需要对系统用户进行权限分类管理,或者需要根据岗位分配不同访问能力的业务系统中,使用 dvadmin/system/views/role.py
定义的角色管理模块。例如:将用户按部门或职位分配为不同角色,每个角色对应不同的系统菜单、操作按钮、数据访问范围,确保系统安全性和高效性。角色管理作为 RBAC(基于角色的访问控制)实现的基础,是后台权限系统不可缺少的一环。
使用场景 | 说明 |
---|---|
企业组织架构管理 | 不同部门设置不同角色,分配对应的菜单及操作权限 |
系统功能模块细粒度权限控制 | 角色绑定特定按钮权限,控制页面操作功能开关 |
数据安全合规场景 | 角色配置数据范围权限,防止越权访问敏感数据 |
行业系统定制化 | 针对行业需求自定义角色权限组合,提高系统灵活性 |
后台权限管理中心 | 统一配置用户角色及权限资源,减少维护成本 |
项目源码解析
角色基本信息序列化器
用于序列化角色对象,额外处理角色关联的用户列表,只保留用户ID、名称和所属部门名称。与 Role
和 Users
表关联,主要用于角色管理列表展示和详情展示。
python
class RoleSerializer(CustomModelSerializer):
users = serializers.SerializerMethodField()
@staticmethod
def get_users(instance):
users = instance.users_set.exclude(id=1).values('id', 'name', 'dept__name')
return users
class Meta:
model = Role
fields = "__all__"
read_only_fields = ["id"]
角色创建与更新序列化器
专门处理角色新增和更新时的序列化,增加了对菜单、部门、按钮权限的嵌套展示,同时对角色名称和权限标识字段做唯一性校验。依赖 MenuSerializer
、DeptSerializer
、MenuButtonSerializer
子序列化器,保证数据准确性。
python
class RoleCreateUpdateSerializer(CustomModelSerializer):
menu = MenuSerializer(many=True, read_only=True)
dept = DeptSerializer(many=True, read_only=True)
permission = MenuButtonSerializer(many=True, read_only=True)
key = serializers.CharField(
max_length=50,
validators=[CustomUniqueValidator(queryset=Role.objects.all(), message="权限字符必须唯一")]
)
name = serializers.CharField(max_length=50, validators=[CustomUniqueValidator(queryset=Role.objects.all())])
class Meta:
model = Role
fields = '__all__'
角色菜单按钮权限序列化器
为角色返回对应菜单下的按钮权限列表。根据是否为超级管理员动态筛选按钮,普通用户只能看到自己有权限的按钮,用于菜单树权限勾选界面。
python
class MenuPermissionSerializer(CustomModelSerializer):
menuPermission = serializers.SerializerMethodField()
def get_menuPermission(self, instance):
is_superuser = self.request.user.is_superuser
if is_superuser:
queryset = MenuButton.objects.filter(menu__id=instance.id)
else:
menu_permission_id_list = self.request.user.role.values_list('permission', flat=True)
queryset = MenuButton.objects.filter(id__in=menu_permission_id_list, menu__id=instance.id)
serializer = MenuButtonSerializer(queryset, many=True, read_only=True)
return serializer.data
class Meta:
model = Menu
fields = ['id', 'parent', 'name', 'menuPermission']
菜单按钮权限勾选状态序列化器
用于前端权限设置界面,标记当前菜单是否有按钮权限绑定。超级管理员默认全部勾选,普通用户根据权限表判断是否勾选。
python
class MenuButtonPermissionSerializer(CustomModelSerializer):
isCheck = serializers.SerializerMethodField()
def get_isCheck(self, instance):
is_superuser = self.request.user.is_superuser
if is_superuser:
return True
else:
return MenuButton.objects.filter(
menu__id=instance.id,
role__id__in=self.request.user.role.values_list('id', flat=True)
).exists()
class Meta:
model = Menu
fields = '__all__'
角色管理接口控制器
综合管理角色的增删改查、分配用户、移除用户等操作。继承自 CustomModelViewSet
、FastCrudMixin
、FieldPermissionMixin
,具备自定义权限控制、快速增删改查功能,与用户、部门、菜单、按钮权限等模块协作密切。
python
class RoleViewSet(CustomModelViewSet, FastCrudMixin, FieldPermissionMixin):
queryset = Role.objects.all()
serializer_class = RoleSerializer
create_serializer_class = RoleCreateUpdateSerializer
update_serializer_class = RoleCreateUpdateSerializer
search_fields = ['name', 'key']
为某个角色动态添加或移除用户,支持双向操作。根据前端传来的 direction
参数决定是授权还是取消授权,修改 users_set
关系表。
python
@action(methods=['PUT'], detail=True, permission_classes=[IsAuthenticated])
def set_role_users(self, request, pk):
data = request.data
direction = data.get('direction')
movedKeys = data.get('movedKeys')
role = Role.objects.get(pk=pk)
if direction == "left":
role.users_set.remove(*movedKeys)
else:
role.users_set.add(*movedKeys)
serializer = RoleSerializer(role)
return DetailResponse(data=serializer.data, msg="更新成功")
查询某个角色下已授权和未授权的用户,支持按用户姓名和部门筛选。常用于角色授权管理界面,提升权限分配体验。
python
@action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated, CustomPermission])
def get_role_users(self, request):
role_id = request.query_params.get('role_id', None)
if not role_id:
return ErrorResponse(msg="请选择角色")
if request.query_params.get('authorized', 0) == "1":
queryset = Users.objects.filter(role__id=role_id).exclude(is_superuser=True)
else:
queryset = Users.objects.exclude(role__id=role_id).exclude(is_superuser=True)
if name := request.query_params.get('name', None):
queryset = queryset.filter(name__icontains=name)
if dept := request.query_params.get('dept', None):
queryset = queryset.filter(dept=dept)
page = self.paginate_queryset(queryset.values('id', 'name', 'dept__name'))
if page is not None:
return self.get_paginated_response(page)
return SuccessResponse(data=page)
删除指定角色下的某个用户授权关系,简化了授权关系维护逻辑。用户通过 user_id
参数指定,防止误操作。
python
@action(methods=['DELETE'], detail=True, permission_classes=[IsAuthenticated, CustomPermission])
def remove_role_user(self, request, pk):
user_id = request.data.get('user_id', None)
if not user_id:
return ErrorResponse(msg="请选择用户")
role = self.get_object()
role.users_set.remove(*user_id)
return SuccessResponse(msg="删除成功")
为指定角色批量添加多个用户,支持一次性多选操作,提升角色配置效率。通过 users_id
参数传递用户列表。
python
@action(methods=['POST'], detail=True, permission_classes=[IsAuthenticated, CustomPermission])
def add_role_users(self, request, pk):
users_id = request.data.get('users_id', None)
if not users_id:
return ErrorResponse(msg="请选择用户")
role = self.get_object()
role.users_set.add(*users_id)
return DetailResponse(msg="添加成功")
应用案例
角色权限配置在后台系统中的权限管理落地实践
后台管理系统通常需要对用户的操作能力进行精细化限制,例如谁能访问某个菜单、点击哪个按钮、查看哪些数据字段。项目通过 dvadmin/system/views/role.py
模块构建了一套完整的角色权限控制体系,支持角色的增删改查、用户授权、菜单按钮绑定、数据范围设置等功能。管理员可通过后台角色配置界面,动态为角色分配权限,系统根据角色配置自动生效,确保安全性与灵活性并重。
功能点 | 内容描述 |
---|---|
场景需求 | 对用户操作能力进行精细化限制,控制谁能访问某菜单、点击哪个按钮、查看哪些数据字段,确保系统安全性与灵活性。 |
核心模块 | dvadmin/system/views/role.py :构建角色权限控制体系,统一管理权限分配与授权操作。 |
支持功能 | - 角色管理:支持角色的增删改查功能。 |
- 用户授权:为角色动态分配用户,控制用户的权限范围。 | |
- 菜单按钮绑定:角色可绑定菜单、按钮权限,控制访问范围和可操作项。 | |
- 数据范围设置:支持为角色自定义数据范围权限(如部门、组织级别)。 | |
权限数据管理 | - 标准接口:提供角色权限数据的增删改查接口,供前端加载角色详情、用户授权状态与权限树。 |
- 多对多绑定:角色与菜单、按钮、字段、用户通过多对多关系绑定,高效维护权限结构。 | |
控制器逻辑 | - RoleViewSet:统一调度接口调用逻辑,通过自定义 action 实现动态授权与数据分配。 |
前端交互 | - 动态加载角色权限树,展示绑定的菜单、按钮与字段权限。 - 支持在角色配置界面实时更新权限并立即生效。 |
应用场景 | - 菜单权限管理 :控制用户可访问的菜单项。 - 按钮权限管理 :控制用户可操作的功能按钮。 - 字段权限管理:控制用户可查看或编辑的字段范围。 |
优势 | - 提供精细化权限控制,确保系统安全性。 - 动态配置权限,提升管理效率与灵活性。 |
扩展能力 | - 支持复杂的多角色、多权限层级场景。 - 可结合其他权限模块(如字段级权限、按钮级权限)构建完整权限体系。 |
模块中所有角色权限数据均通过标准接口进行增删改查,前端通过接口可加载角色详情、用户授权状态、权限树等内容。角色与菜单、按钮、字段、用户等模型之间通过多对多关系绑定,实现权限关系的高效维护。接口调用逻辑统一由 RoleViewSet
控制器调度,通过自定义 action 实现动态授权与数据分配。
角色权限配置的实际操作代码逻辑
以为某角色添加用户为例,管理员在权限管理页面选择角色并勾选多个用户,前端将以下请求发送至后端:
http
POST /api/system/role/3/add_role_users/
{
"users_id": [7, 8, 12]
}
后端调用如下方法,将这些用户添加至角色 ID 为 3 的角色中:
python
def add_role_users(self, request, pk):
users_id = request.data.get('users_id', None)
role = self.get_object()
role.users_set.add(*users_id)
return DetailResponse(msg="添加成功")
若需移除角色中的用户,则调用:
http
DELETE /api/system/role/3/remove_role_user/
{
"user_id": 7
}
调用逻辑将目标用户从当前角色中解除绑定关系:
python
def remove_role_user(self, request, pk):
user_id = request.data.get('user_id', None)
role = self.get_object()
role.users_set.remove(*user_id)
return SuccessResponse(msg="删除成功")
权限配置完成后,前端通过菜单权限树接口加载菜单及按钮列表:
http
GET /api/system/menu/permissions/?role_id=3
系统根据用户是否为超级管理员自动判断勾选状态,返回如下格式的数据:
json
[
{
"id": 5,
"name": "系统管理",
"menuPermission": [
{"id": 21, "label": "新增"},
{"id": 22, "label": "编辑"},
{"id": 23, "label": "删除"}
]
}
]
管理员可点击界面直接勾选按钮权限,系统保存后更新角色与 MenuButton
的关联关系,页面立即生效。整套机制将用户权限、页面元素、数据范围解耦,形成基于角色的多维权限系统,适用于各类企业、组织结构复杂的管理平台。
总结
模块基于标准 ViewSet 架构,结合序列化器实现角色及权限数据的统一校验与处理,保证接口一致性。增删改查、角色授权与按钮权限勾选功能通过自定义接口扩展,覆盖了常见权限管理场景,具备较好的灵活性与业务适配能力。
接口粒度较细但存在重复逻辑,部分校验可进一步抽象提升代码复用率。权限设置接口依赖数据库同步查询,面对大规模数据时可能存在性能瓶颈。若重写,可引入批量授权优化、异步处理及权限缓存机制,提升整体执行效率与扩展性。