Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Customize JSON output in Django Rest Framework GET call

I'm attempting to retrieve a filtered list from a MySQL database. The query itself looks fine, but the JSON returned shows this:

[
{
    "id": "0038",
    "name": "Jane Doe",
    "total_hrs_per_week": 6,
    "timezone": "America/Los_Angeles"
},
{
    "id": "0039",
    "name": "John Doe",
    "total_hrs_per_week": 10,
    "timezone": "America/Los_Angeles"
}]

when the spec that I need to build to wants this:

{
"people":[
{
    "id": "0038",
    "name": "Jane Doe",
    "total_hrs_per_week": 6,
    "timezone": "America/Los_Angeles"
},
{
    "id": "0039",
    "name": "John Doe",
    "total_hrs_per_week": 10,
    "timezone": "America/Los_Angeles"
}]}

Here's my serializer

class PeopleListSerializer(serializers.ModelSerializer):
    id = serializers.CharField(source='id')
    name =serializers.CharField(source='name')
    total_hrs_per_week = serializers.IntegerField(source='total_hrs_per_week')
    timezone = serializers.CharField(source='timezone')

    class Meta:
        model = models.Person
        fields = ('id','name','total_hrs_per_week','timezone')

Any idea how to wrap the returned results in this way?

EDIT:

I tried wrapping this in another serializer like so

    class PeopleListWrapperSerializer(serializers.Serializer):
        people = PeopleListSerializer(many=True)

        class Meta:
            fields = ['people']

But this throws the following error:

Got AttributeError when attempting to get a value for field people on serializer PeopleListWrapperSerializer. The serializer field might be named incorrectly and not match any attribute or key on the Person instance. Original exception text was: 'Person' object has no attribute 'people'.

like image 334
L. W. Avatar asked May 11 '16 16:05

L. W.


People also ask

What is the difference between ModelSerializer and HyperlinkedModelSerializer?

The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys. By default the serializer will include a url field instead of a primary key field.

What is renderers in Django REST Framework?

The rendering process takes the intermediate representation of template and context, and turns it into the final byte stream that can be served to the client. REST framework includes a number of built in Renderer classes, that allow you to return responses with various media types.


2 Answers

You can do that by overriding the list() method.

class PeopleListView(ListAPIView):

    def list(self, request, *args, **kwargs):
        # call the original 'list' to get the original response
        response = super(PeopleListView, self).list(request, *args, **kwargs) 

        # customize the response data
        response.data = {"people": response.data} 

        # return response with this custom representation
        return response 
like image 198
Rahul Gupta Avatar answered Sep 28 '22 17:09

Rahul Gupta


Depending on how you'll want incoming data and your models, you can:

  • use nested serializers
  • Customize the renderers and the parser
  • Override the default view methods and wrap the serializer's result in your own expected output
like image 29
Linovia Avatar answered Sep 28 '22 18:09

Linovia