Simran Saha
Simran Saha

Reputation: 13

Return custom JSON response from ListAPIView Django 3.0 Rest Framework

I have created an API using DRF That is able to list and view particular records based on the URL pattern specified. For example:

for the request:

curl -v http://127.0.0.1:8000/get_details/120001/

I am able to get a response:

[
    {
        "subject": "Data Structures",
        "course": "CSE"
    },
    {
        "subject": "Thermodynamics",
        "course": "Chemistry"
    },
    {
        "subject": "Organic Chemistry",
        "course": "Chemistry"
    },
    {
        "subject": "Optics",
        "course": "Physics"
    }
]

Where '120001' is the user_id the database is searched against. But the I want the response in the following format:

{'Chemistry': ['Thermodynamics', 'Organic Chemistry'], 'CSE': ['Data Structures'], 'Physics': ['Optics']}

(content wise, I am not considering indentation and other factors)

While I am able to write code for the logic of how to create and populate this dictionary, I am unable to figure out how to return this as response and from where.

I am using generics.ListAPIView as the view class.

Here is my model (models.py):

class Subject(models.Model):
    user_id = models.CharField(null = False, max_length=10)
    subject = models.CharField(max_length=50)
    course = models.CharField(max_length=50)

    def __str__(self):
        return self.subject

Serializer (serializers.py):

class SubjectSerializer(serializers.ModelSerializer):
    class Meta:
        model = Subject
        fields = ['subject', 'course']

and, views.py (for the first output in default format):

class SubjectView(generics.ListAPIView):
    serializer_class = SubjectSerializer

    def get_queryset(self):
        username = self.kwargs['user_id']
        return Subject.objects.filter(user_id = username).only('subject','course')

I have written a logic to create the dictionary to send as response (as described in my desired output) by extracting values using Subject.objects.values(....) and then looping through the results to create my dictionary but I just don't get where (that is, which function) to write it in and return from.

Is there any function provided by the generics.ListAPIView class that can allow me to do this? And if not, then what other alternative approach can I try?

I am an absolute beginner at Django and any help will be appreciated. Also, it will be of great help if anyone can suggest me a practical guide/tutorial/playlist from where I can learn DRF through code examples to speed up my learning process.

Thank you!

Upvotes: 1

Views: 2943

Answers (1)

Nishant Nawarkhede
Nishant Nawarkhede

Reputation: 8400

You need to override to_representation method of Serializer

from docs

There are some cases where you need to provide extra context to the serializer in addition to the object being serialized.

class SubjectSerializer(serializers.ModelSerializer):
    class Meta:
        model = Subject
        fields = ['subject', 'course']

    def to_representation(self, instance):
        data = super(SubjectSerializer, self).to_representation(instance)
        # manipulate data here 
        return data

Upvotes: 4

Related Questions