0

Currently I'm learning Django and Django Rest framework and I am working on an API project. The project is about returning simple statistics about text records from database. I want to list ten most common words from the database.

This is models.py file:

from django.db import models

class Word(models.Model):
    word = models.CharField(max_length = 100)
    word_count = models.IntegerField()

    class Meta:
        db_table = 'djangorest_word'
        managed = False

And this is view.py file:

from rest_framework.response import Response
from rest_framework import generics
from djangorest.api.models import Word, Author, WordPerAuthor
from djangorest.api.serializers import WordSerializer, AuthorSerializer, WordPerAuthorSerializer
from django.db.models import Sum 

class WordList(generics.ListAPIView):
    queryset = Word.objects.values('word', 'word_count').order_by('word_count').annotate(Sum('word_count'))[:10]
    serializer_class = WordSerializer
    def get(self, request):
        queryset = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(queryset, many=True)
        data = {obj['word']: obj['word_count'] for obj in serializer.data}
        return Response(data)

Ascending order works properly:

{
    "Karolina": 1,
    "hand": 1,
    "correctness": 1,
    "inform": 1,
    "memory": 1,
    "Possible": 1,
    "modules": 1,
    "guy": 1,
    "pitching": 1,
    "expensive": 1
}

But whenever I use order_by('-word_count') or order_by('word_count').reverse() there isn't ten words but only two:

{
    "the": 1120,
    "to": 1104
}

I don't understand why order_by works properly in ascending order but doesn't work in descending. Am I missing something? Is there other way to achieve receiving top ten values?

zubmic
  • 77
  • 1
  • 4
  • 10

1 Answers1

1

The ordering of QuerySet functions is important when annotations are involved. In particular, you want to sort after annotating. This answer has a good example.

So in your case:

Word.objects.values('word') \
    .annotate(word_count=Sum('word_count')) \
    .order_by('-word_count')[:10]
GavinH
  • 2,173
  • 1
  • 15
  • 17