如何在Django Rest Framework中格式化组与权限的序列化响应?
解决方案
要实现期望的返回格式,需要重写DRF序列化器的to_representation方法,自定义数据结构,将权限按模块分组并映射为指定的can_*字段。
修改后的Serializer.py
from rest_framework import serializers from django.contrib.auth.models import Group, Permission class RolePermissionSerializer(serializers.ModelSerializer): class Meta: model = Group fields = ["id", "name"] def to_representation(self, instance): # 构建基础返回结构 response_data = { "role_name": instance.name, "modules": [] } # 预加载关联的ContentType,避免N+1查询 permissions = instance.permissions.select_related('content_type').all() # 按模块(ContentType)分组权限 module_permission_map = {} # 定义权限codename到目标字段的映射 action_field_map = { 'view': 'can_view', 'add': 'can_add', 'change': 'can_edit', 'delete': 'can_delete', 'print': 'can_print', 'deactivate': 'can_deactivate', 'import': 'can_import', 'export': 'can_export' } for perm in permissions: module_name = perm.content_type.name.capitalize() codename_prefix = perm.codename.split('_')[0] # 如果模块未初始化,创建默认结构(所有权限默认False) if module_name not in module_permission_map: module_permission_map[module_name] = { "module_name": module_name, "can_view": "False", "can_add": "False", "can_edit": "False", "can_delete": "False", "can_print": "False", "can_deactivate": "False", "can_import": "False", "can_export": "False" } # 匹配到映射关系则设置为True if codename_prefix in action_field_map: module_permission_map[module_name][action_field_map[codename_prefix]] = "True" # 将分组后的模块转为列表,加入返回数据 response_data["modules"] = list(module_permission_map.values()) return response_data
关键说明
- 自定义序列化逻辑:通过
to_representation方法完全控制输出结构,替代默认的模型字段序列化。 - 优化查询:使用
select_related('content_type')一次性加载权限关联的ContentType,避免多次数据库查询。 - 权限分组与映射:
- 按ContentType的名称(即模块名)对权限分组
- 将权限codename的前缀(如
add、view)映射为期望的can_*字段 - 初始化所有权限字段为
"False",存在对应权限时设为"True"
- 兼容多模块:如果角色拥有其他模块(如Group、Permission)的权限,会自动按模块分组输出。
视图无需修改
原View.py中的RolePermissionListCreateAPIView可以直接使用修改后的序列化器,返回数据会自动转换为期望格式。
内容的提问来源于stack exchange,提问作者o3cloud
相关产品推荐
相关产品推荐

