Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - How can you include annotated results in a serialized QuerySet?

How can you include annotated results in a serialized QuerySet?

data = serializer.serialize(Books.objects.filter(publisher__id=id).annotate(num_books=Count('related_books')), use_natural_keys=True)

However the key/value pare {'num_books': number} is not include into the json result.

I've been searching for similar questions on the internet, but i didn't found a solution that worked for me.

Here is a similar case: http://python.6.x6.nabble.com/How-can-you-include-annotated-results-in-a-serialized-QuerySet-td67238.html

Thanks!

like image 837
Nunovsky Avatar asked Aug 20 '14 09:08

Nunovsky


People also ask

What is annotate in Django Queryset?

annotate()Annotates each object in the QuerySet with the provided list of query expressions.

How do I serialize Queryset?

To serialize a queryset or list of objects instead of a single object instance, you should pass the many=True flag when instantiating the serializer. You can then pass a queryset or list of objects to be serialized.

Why we use annotate in Django ORM?

The Django ORM is a convenient way to extract data from the database, and the annotate() clause that you can use with QuerySets is also a useful way to dynamically generate additional data for each object when the data is being extracted.

How does Django annotation work?

In the Django framework, both annotate and aggregate are responsible for identifying a given value set summary. Among these, annotate identifies the summary from each of the items in the queryset. Whereas in the case of aggregate, the summary is calculated for the entire queryset.


2 Answers

As shown in this post you can use SerializerMethodField in your Serializer:

class BooksSerializer(serializers.ModelSerializer):

  num_books = serializers.SerializerMethodField()

  def get_num_books(self, obj):
    try:
        return obj.num_books
    except:
        return None

It will serialize the annotated value (readonly)

like image 39
Martin Faucheux Avatar answered Oct 08 '22 18:10

Martin Faucheux


I did some research and found that serializer.serialize can only serialize queryset, and annotation just adds an attribute with each object of the queryset, so when you try to serialize a query, annotated fields aren't shown. This is my way of implementation:

from django.core.serializers.json import DjangoJSONEncoder

books = Books.objects.filter(publisher__id=id).annotate(num_books=Count('related_books')).values()
json_data = json.dumps(list(books), cls=DjangoJSONEncoder)
like image 126
ruddra Avatar answered Oct 08 '22 18:10

ruddra