DRF:如何为权限组返回名称而不是ID?

时间:2020-08-13 10:53:27

标签: django django-rest-framework

我们有一个Client模型和一个ClientTeamMember模型,该模型允许一个或多个团队成员分配给每个客户。我们网站上的TeamMember是用户帐户的个人资料扩展名。

在ClientTeamMember表中,我们还有一个groups字段,该字段与Group中定义的/django/contrib/auth模型相同。其目的是能够为特定客户端将组(角色)分配给TeamMember,从而为他们赋予其他客户端所没有的额外权限。例如,让团队成员成为仅一名客户的“项目经理”。

我们的型号:

class Client(models.Model):

    name = models.CharField(max_length=100)


class ClientTeamMember(models.Model):

    client = models.ForeignKey(
        Client,
        related_name='client_team_members',
    )
    team_member = models.ForeignKey(
        TeamMember,
        related_name='team_member_clients',
    )
    groups = models.ManyToManyField(
        Group,
        blank=True,
        default='',
        related_name='client_groups',
    )

我们要在客户端序列化器中返回组名(而不仅仅是ID)。像这样:

    "results": [
        {
            "id": 9,
            "name": "Acme Honey",
            "permission_groups": [
                "Project Manager"
            ]
        }
    ]

就像在用户模型上一样,“组”是一个多对多字段,允许在任何级别分配多个组。

以下是序列化器:

class GroupNameSerializer(serializers.ModelSerializer):

    class Meta:
        model = Group
        fields = ['name']


class ClientGroupsSerializer(serializers.ModelSerializer):

    groups = GroupNameSerializer(many=True, read_only=True)

    class Meta:
        model = ClientTeamMember
        fields = 'groups'


class ClientSerializer(serializers.ModelSerializer):

    permission_groups = ClientGroupsSerializer(source='client_team_members', many=True)

    class Meta:
        model = Client
        fields = '__all__'

使用上面的配置,它返回的是:

    "results": [
        {
            "id": 9,
            "name": "Acme Honey",
            "permission_groups": [
                {
                    "groups": [
                        {}
                    ]
                }
            ]
        }
    ]

如果我删除groups = GroupNameSerializer(...)行,并将字段更改为__all__,则会得到以下提示:

    "results": [
        {
            "id": 9,
            "name": "Acme Honey",
            "permission_groups": [
                {
                    "id": 1,
                    "client": 9,
                    "team_member": 3
                }
            ]
        }
    ]

...所以我知道它正在获得ClientTeamMember行(这是“项目经理”组所在的位置)。不过,我不明白为什么在这种情况下它不包含groups字段。

我尝试过的事情:

  • 添加的级别= 1、2等。
  • 更改了ClientGroupSerializer中“ groups”字段的名称,并向其中添加了source="groups"
  • 将组更改为ReadOnlyField(并更改其名称)。
  • 覆盖ClientGroupSerializer中的to_representation方法

最终的目标是返回名称列表,而不是上面的第一个“结果”示例所示的"name": "Project Manager"

1 个答案:

答案 0 :(得分:1)

您可以这样:

class ClientSerializer(serializers.ModelSerializer):

    permission_groups = serializers.SerializerMethodField('get_group_names')

    class Meta:
        model = Client
        fields = ('id','name','permission_groups')

    def get_group_names(self,obj):
        group_name_list = [group.name for group in obj.client_team_members] #assuming group has a name field
        return group_name_list