Django序列化器输出作为JSON对象的一部分

时间:2019-05-02 10:06:01

标签: python django django-rest-framework

上下文

我有2个模型:CustomerDeviceGroup

当前,我有一个API端点/api/v1/device-groups/?customer_uuid=<customer_uuid>,它返回与给定DeviceGroups相关的Customer,如下所示:

[
    {
        "group_uuid": "c61361ac-0826-41bb-825a-8aa8e014ae0c",
        "device_group_name": "Default",
        "color": "0a2f45",
        "is_default": true
    },
    {
        "group_uuid": "1a86e8e4-b41b-4f33-aefb-ce984ef96144",
        "device_group_name": "Testgroup",
        "color": "123456",
        "is_default": false
    }
] 

目标

我希望DeviceGroups的数组成为这样的对象的一部分:

"device_groups": 
[
    {
        "group_uuid": "c61361ac-0826-41bb-825a-8aa8e014ae0c",
        "device_group_name": "Default",
        "color": "0a2f45",
        "is_default": true
    },
    {
        "group_uuid": "1a86e8e4-b41b-4f33-aefb-ce984ef96144",
        "device_group_name": "Testgroup",
        "color": "123456",
        "is_default": false
    }
] 

模型

# models.py

class Customer(models.Model):
    customer_uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, db_index=True)
    customer_name = models.CharField(max_length=128, unique=True)


class DeviceGroup(models.Model):
    group_uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, db_index=True)
    customer_uuid = models.ForeignKey(Customer, on_delete=models.DO_NOTHING)
    device_group_name = models.CharField(max_length=20)
    color = models.CharField(max_length=10)
    is_default = models.BooleanField(default=False)

序列化器

# serializers.py

class DeviceGroupSerializer(serializers.ModelSerializer):
    class Meta:
        model = DeviceGroup
        fields = ('group_uuid', 'device_group_name', 'color', 'is_default')

查看

# views.py

class DeviceGroupCustomerViewSet(viewsets.ModelViewSet):
    serializer_class = DeviceGroupSerializer

    def get_queryset(self):
        return DeviceGroup.objects.filter(customer_uuid=self.request.GET['customer_uuid'])

我尝试创建一个新的serializer,但是并不能解决我的问题:

class TestSerializer(serializers.ModelSerializer):
    device_groups = DeviceGroupSerializer(many=True, read_only=True)

    class Meta:
        model = DeviceGroup
        fields = ('device_groups', 'group_uuid', 'device_group_name', 'color', 'is_default')

为了获得所需的输出,我需要更改什么?

3 个答案:

答案 0 :(得分:4)

您可以像这样更新视图

def list(self, request):
    queryset = DeviceGroup.objects.filter(customer_uuid=self.request.GET['customer_uuid'])
    serializer = UserSerializer(queryset, many=True)
    return Response({'device_groups': serializer.data})

这将获得所需的输出。

答案 1 :(得分:4)

只需按照以下方式修改名为 TestSerializer 的新序列化器即可。

class TestSerializer(serializers.Serializer):
    device_groups = serializers.SerializerMethodField(read_only=True)

    def get_device_groups(self, model):
        return DeviceGroupSerializer(model).data

响应将是分页响应。如果要禁用它,只需在ModelViewset类中将pagination_class提到为None。

答案 2 :(得分:1)

要在不失去分页的情况下轻松实现此目的,我会这样做:

from rest_framework.pagination import PageNumberPagination 

class DeviceGroupPagination(PageNumberPagination):

    def get_paginated_response(self, data):
        return Response(OrderedDict([
            ('count', self.page.paginator.count),
            ('next', self.get_next_link()),
            ('previous', self.get_previous_link()),
            ('device_groups', data)
        ]))

然后在视图中

class DeviceGroupCustomerViewSet(viewsets.ModelViewSet):
    serializer_class = DeviceGroupSerializer
    pagination_class = DeviceGroupPagination
    ...

现在,您将拥有results代替device_groups