Home > Software design >  Django order by vote percentage
Django order by vote percentage

Time:10-03

I currently have a post that has upvotes and downvotes.

the model looks something like this

class Word(models.Model):
    name = models.CharField(max_length=250)
    upvotes = models.ManyToManyField(User, blank=True, related_name='threadUpVotes')
    downvotes = models.ManyToManyField(User, blank=True, related_name='threaddDownVotes')

in my views.py I have so far gotten this far

from django.db.models import F, Sum

words = Word.objects.filter(name__iexact='test').annotate(
            total_votes=Sum(F('upvotes')   F('downvotes'))).order_by('total_votes')

But I'm unsure what to do next to get it to rank by say the one with most upvotes vs downvotes.

CodePudding user response:

I realized after I posted, I sumply had to divided the upvotes by the total number of votes and order in reverse.

words = Word.objects.filter(name__iexact='test').annotate(
            total_votes=Sum(F('upvotes'))/Sum(F('upvotes')   F('downvotes'))).order_by('-total_votes')

CodePudding user response:

You can make use of a Count expression [Django-doc] with distinct=True [Django-doc], otherwise you will count an upvote as many times there are downvotes and vice versa. We thus can determine the share of upvotes with:

from django.db.models import Count

words = Word.objects.filter(
    name__iexact='test'
).annotate(
    total_votes=Count('upvotes', distinct=True) / (Count('upvotes', distinct=True)   Count('downvotes', distinct=True))
).order_by('total_votes')

CodePudding user response:

You ham many to many field, You should use:

from django.db.models import F, Sum, Count

words = Word.objects.filter(name__iexact='test').annotate(
    total_votes=Count('upvotes') - Count('downvotes')).order_by('-total_votes')

or in your answer:

from django.db.models import F, Sum, Count

words = Word.objects.filter(name__iexact='test').annotate(
    total_votes=Count('upvotes') / (Count('upvotes')   Count('downvotes'))).order_by('-total_votes')
  • Related