Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django rest framework json serializer

I want json response from Django rest framework,so I have Json Response like this: .

[
    {
        "id": 1,
        "TitleEnglish": "Tiny Talents Program",
        "TitleArabic": "Tiny Talents Program",
        "DescriptionEnglish": "Timing: 8:00 am till 1:00 pm",
        "DescriptionArabic": "Timing: 8:00 am till 1:00 pm",
        "CategoryEnglish": "Art & Education ",
        "CategoryArabic": "Art & Education ",
        "Date": "2015-05-07",
        "Status": true,
        "Image": "--"
    }
]

but i need response like this:

{
"data": [
    {
        "id": 1,
        "TitleEnglish": "Tiny Talents Program",
        "TitleArabic": "Tiny Talents Program",
        "DescriptionEnglish": "Timing: 8:00 am till 1:00 pm",
        "DescriptionArabic": "Timing: 8:00 am till 1:00 pm",
        "CategoryEnglish": "Art & Education ",
        "CategoryArabic": "Art & Education ",
        "Date": "2015-05-07",
        "Status": true,
        "Image": "--"
    }
       ]
}

My serializer code is :

class PromotionSerializer(serializers.HyperlinkedModelSerializer):
    CategoryEnglish  = serializers.CharField(read_only=True, source="Category.TitleEnglish")
    CategoryArabic  = serializers.CharField(read_only=True, source="Category.TitleArabic")
    class Meta:
        model = Promotion
        fields = ('id', 'TitleEnglish', 'TitleArabic', 'DescriptionEnglish', 'DescriptionArabic', 'CategoryEnglish','CategoryArabic', 'Date','Status','Image')
like image 958
Muhammad Naeem Paracha Avatar asked Aug 06 '15 10:08

Muhammad Naeem Paracha


2 Answers

I solved my problem by changing in my Views:

I added a list method, my problem is solved:

def list(self, request):
    queryset = Promotion.objects.all()
    serializer_class = PromotionSerializer(queryset, many=True)
    serialized_data =  {'data': serializer_class.data}
    return Response(serialized_data)
like image 171
Muhammad Naeem Paracha Avatar answered Sep 28 '22 08:09

Muhammad Naeem Paracha


I think you can do that by customizing the ListSerializer behavior which is used when creating serialized response for list requests.

We can create a custom PromotionListSerializer which will be used when multiple instances are passed to serializer for serialization using many=Tue argument.

We override the data property in our PromotionListSerializer class to return our custom representation instead.

class PromotionListSerializer(serializers.ListSerializer):

    @property
    def data(self):
        # call the super() to get the default serialized data
        serialized_data =  super(PromotionListSerializer, self).data       
        custom_representation = {'data': serialized_data} # insert the above response in a dictionary
        return custom_representation

Then in your PromotionSerializer, specify this custom list serializer class in Meta. This custom list serializer class will be used then when serializing multiple instances.

class PromotionSerializer(serializers.HyperlinkedModelSerializer):
    CategoryEnglish  = serializers.CharField(read_only=True, source="Category.TitleEnglish")
    CategoryArabic  = serializers.CharField(read_only=True, source="Category.TitleArabic")
    class Meta:
        model = Promotion
        fields = ('id', 'TitleEnglish', 'TitleArabic', 'DescriptionEnglish', 'DescriptionArabic', 'CategoryEnglish','CategoryArabic', 'Date','Status','Image')

        # define the custome list serializer class to be used
        list_serializer_class = PromotionListSerializer

Solution-2:

Override the list method of the view and return custom representation instead of the default response which you have done as mentioned in your ans.

Extending the OP's answer, this will provide support for paginated response also. This is the actual code in DRF and i have just returned the custom_representation instead of serializer.data at the end.

def list(self, request, *args, **kwargs):
    instance = self.filter_queryset(self.get_queryset())
    page = self.paginate_queryset(instance)
    if page is not None:
        serializer = self.get_pagination_serializer(page)
    else:
        serializer = self.get_serializer(instance, many=True)
    serialized_data = serializer.data
    custom_representation = {'data': serialized_data}
    return Response(custom_representation)
like image 25
Rahul Gupta Avatar answered Sep 28 '22 09:09

Rahul Gupta