How do I store a count of a manytomanyfield in a model or filter and aggregate a manytomanyfield

Viewed 30

I have a model where I want to create a ranking for the count of a manytomanyfield. Only it expects an integer field instead of a manytomany field. I have a problem with the votes__lt.

Would the best course of action be creating a votes_count integerfield that counts the votes or is there a way to fix this code so it works?

class ContestEntry(TimeStampedModel):
   votes = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='vote_entry')

   def ranking(self):
        aggregate = ContestEntry.objects.filter(votes__lt=Count(self.votes)).aggregate(ranking=Count('votes'))
        return aggregate['ranking'] + 1
1 Answers

You can use .annotate for this:

def ranking(self):
    return ContestEntry.objects.annotate(
        nvotes=Count('votes')
    ).filter(
        nvotes__gt=self.votes.all().count()
    ).count()

Here we thus first annotate the ContestEntrys with the number of votes nvotes, and then we count how many ContestEntrys there are with more nvotes than the number of votes of the self object.

Related