0

I have to add an extra field using annotate in the get api. The field is something like count of a field of all the objects, not a particular object. And I want it to appear just once in the response of get api. If I use annotate, it appears on all the objects response. How can it be achieved??

My model:

class Package(models.Model):
    location = models.CharField()
    bought_times = models.IntegerField(default=0)
    /....................../

Now if I use annotate something like this:

qs = Package.objects.filter(....).annotate(whole_bought_counts=Sum("bought_times") or some logic)

In the response it will come like:

{
id = 1,
localtion = Paris,
bought_times = 22,
whole_bought_counts =72,
}
{
id = 1,
localtion = Miami,
bought_times = 16,
whole_bought_counts =72,
}
id = 1,
localtion = Switzerland,
bought_times = 24,
whole_bought_counts =72,
}

I need the whole_bought_counts to appear just to appear once, because the count is used for the dashboard info only. Appearing several times will make it appear 100+ times which makes the api quite slow. isnt it??

Reactoo
  • 916
  • 2
  • 12
  • 40
  • I do not think performance will be an issue as I think the query is only executed once. You can, however; achieve what you want, e.g. by overriding the ```list``` method of your viewset. – Chris Jan 09 '22 at 10:24
  • how to override the list method to achieve this?? – Reactoo Jan 09 '22 at 10:27

1 Answers1

1

Additional data can be added to response of a viewset. E.g.

class PackageViewSet(ModelViewSet):

   model = Package
    serializer_class = PackageSerialzer
    queryset = Package.objects.all()

    def get_queryset(self):
        qs = Package.objects.filter(...) # Whatever you want your qs to be
        return qs

    def list(self, request):
        queryset = self.get_queryset()
        serializer = self.serializer_class(queryset, many=True)

        addional_data = {
            'my_data': ... # Any data, from your queryset or else
        }
        
        return Response([addional_data, serializer.data]) 
Chris
  • 2,162
  • 1
  • 6
  • 17
  • does additional_data not need serialization before putting it on response?? – Reactoo Jan 09 '22 at 10:40
  • Not in the example above as the data is already in a format the Response can handle. Of course addional_data can also be the data of any serailizer – Chris Jan 09 '22 at 10:45
  • 1
    Additional information: All the serializer does is transfer your object into a (list of) ```OrderedDict``` - no secret magic – Chris Jan 09 '22 at 10:49
  • whaaaat?? iam so confused..all i learned this time is, serializer is needed to convert the complex queryset into json..now there is not need of serialization, if just passed it into response class...what is happening?? omg!! – Reactoo Jan 09 '22 at 10:53
  • What you learned is correct, don't worry – Chris Jan 09 '22 at 10:58
  • then what is happening here, i am getting json without serialization?? also additional filed can be any data type , here its sum so integer... can you explain....ohh dear lord! – Reactoo Jan 09 '22 at 11:01
  • 1
    The rendering into a JSON response is not done by the serializer but by the ```Response```. From the [docs](https://www.django-rest-framework.org/api-guide/serializers/): "Serializers allow complex data such as querysets and model instances to be converted to native Python datatypes that can then be easily rendered into JSON, XML or other content type" – Chris Jan 09 '22 at 11:20
  • what I learnt till now, was Response class simply converts the single quotation in the serializer data to the double quotation. we can also see that when we see the methods or functions inside the Response class.... – Reactoo Jan 09 '22 at 11:25
  • You might like to read about Response in the [docs](https://www.django-rest-framework.org/api-guide/responses/#responses). They contain a good explanation. – Chris Jan 09 '22 at 11:39