Varun Jain
Varun Jain

Reputation: 1911

Django Rest collecting multiple records into a list

I have a restaurant app and I am making use of serializers to create the api for it. I have a restaurant table and a phone number table. The phone number table references the restaurant_id as a foreign key. Similarly there are other relationships of this sort. I wrote a serializer like this:

class RestaurantOrderSerializer(serializers.ModelSerializer):
    brand = BrandSerializer()
    numbers = PhoneNumberSerializer(many=True)

    class Meta:
        model = Restaurant
        fields = ('brand', 'address', 'id', 'numbers')

What this gives is a nested structure. While in some cases useful over here it becomes unnecessary because PhoneNumberSerializer has a single field. Is there a way to collapse the nesting into a single field for a simpler json?

From this:

{
    "restaurant_name": "Blah Blah:
     ...

    "numbers": {
                 {
                  "number": 123
                },{
                  "number": 456
                  }
                }
}

To:

{
"restaurant_name": "Blah Blah:
...
"numbers": ["123", "456"]

}

Upvotes: 1

Views: 309

Answers (2)

keni
keni

Reputation: 1768

Looks like you already wrote your own serializer, which you do not need in this case. You can use the StringRelatedField(many=True).

from rest_framework import serializers 
class RestaurantOrderSerializer(serializers.ModelSerializer):
    brand = BrandSerializer()
    numbers = serializers.StringRelatedField(many=True)

Upvotes: 1

Rahul Gupta
Rahul Gupta

Reputation: 47876

You can override the to_representation() method to achieve this.

If you need to alter the serialization, deserialization or validation of a serializer class you can do so by overriding the .to_representation() or .to_internal_value() methods.

You need to do something like:

class RestaurantOrderSerializer(serializers.ModelSerializer):
    brand = BrandSerializer()
    numbers = PhoneNumberSerializer(many=True)

    class Meta:
        model = Restaurant
        fields = ('brand', 'address', 'id', 'numbers')

    def to_representation(self, obj):
        # get the default representation
        serialized_data = super(RestaurantOrderSerializer, self).to_representation(obj)
        numbers = serialized_data['numbers'] 
        serialized_data['numbers'] = [x['number'] for x in numbers] # list of numbers
        return serialized_data

Upvotes: 0

Related Questions