1

Context

I have 2 models: Customer & DeviceGroup.

Currently I have an API endpoint /api/v1/device-groups/?customer_uuid=<customer_uuid> which returns the DeviceGroups that are related to the given Customer like this:

[
    {
        "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
    }
] 

Goal

I want the array of DeviceGroups be part of an object like this:

"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

# 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)

Serializer

# serializers.py

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

View

# views.py

class DeviceGroupCustomerViewSet(viewsets.ModelViewSet):
    serializer_class = DeviceGroupSerializer

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

I tried creating a new serializer but it did not solve my problem:

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')

What do I need to change in order to get my desired output?

2
  • 1
    If this API just returns a list of DeviceGroups, I'm finding it difficult to understand why "device_groups": would need to be appended as an object. Do you gain anything from that? Commented May 2, 2019 at 10:19
  • The developer who is working with the response of the API suggested adding "device_groups": as an object as it would be easier for him to handle the data apparently. Commented May 2, 2019 at 11:18

3 Answers 3

3

you can update your views like

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})

this will get the desired output..

Sign up to request clarification or add additional context in comments.

Comments

3

Just modify your new serializer named TestSerializer in the following way.

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

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

The response will be a paginated response. If you want to disable it just mention pagination_class as None in your ModelViewset class.

Comments

1

To achieve this fairly easily without loosing the pagination, I would do this:

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)
        ]))

Then in the views

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

So now, in place of results, you will have device_groups

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.