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

如何在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

关键说明

  1. 自定义序列化逻辑:通过to_representation方法完全控制输出结构,替代默认的模型字段序列化。
  2. 优化查询:使用select_related('content_type')一次性加载权限关联的ContentType,避免多次数据库查询。
  3. 权限分组与映射:
    • 按ContentType的名称(即模块名)对权限分组
    • 将权限codename的前缀(如add、view)映射为期望的can_*字段
    • 初始化所有权限字段为"False",存在对应权限时设为"True"
  4. 兼容多模块:如果角色拥有其他模块(如Group、Permission)的权限,会自动按模块分组输出。

视图无需修改

原View.py中的RolePermissionListCreateAPIView可以直接使用修改后的序列化器,返回数据会自动转换为期望格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 17:40:44