DRF | Django | Up votes | Down Votes

37 views
Skip to first unread message

DJANGO DEVELOPER

unread,
Jun 24, 2021, 10:15:09 AM6/24/21
to Django users
Hi Django experts.
I am building a Django, DRF based mobile app and I want to have functionality of up votes and down votes for posts that user will post.
So what I want to say here that, if an user upvotes a post then it should be get higher ranks as quora questions do. and if there are more down votes than up votes then a post should be moved down ward rather than going up.
I have applied a logic already here and shared the screenshots as well. but I am sure that there is a better logic or solution for this problem.
Thanks in advance.
Mr Mike and Mr Lalit can you guide me here please?
upvote.PNG
modelsupvote.PNG
upvotedata.PNG
upvotecodeexample.PNG

DJANGO DEVELOPER

unread,
Jun 25, 2021, 1:04:25 AM6/25/21
to django...@googlegroups.com
Is there anyone who can help me here?

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/c72fefe7-58d2-4c43-84b8-0faa3d9747b0n%40googlegroups.com.

oba stephen

unread,
Jun 25, 2021, 2:16:14 AM6/25/21
to django...@googlegroups.com
Hi, 

One way would be to create an extra field to track the difference in both fields and then in your meta information on that model set the ordering to that field. 

Another approach which is better is to do something like this. 

Votes.objects.extra(select={'diff': 'upvote - downvote'}).order_by('diff')

Best regards

Stephen Oba

DJANGO DEVELOPER

unread,
Jun 25, 2021, 3:10:15 AM6/25/21
to django...@googlegroups.com
Oba Thank you so much. and let me try it.
and one more thing that I want to ask that how can I calculate the up votes and down votes at the same time? as Facebook likes and dislikes do. can you guide me in this regard?

Chetan Ganji

unread,
Jun 25, 2021, 5:18:36 AM6/25/21
to django...@googlegroups.com
You should have a field on Votes Model diff_vote as integerfield, which will be updated when a user upvote or downvote. 

WHY?? 
Calculating this value on list view will result in higher latency. 
So we can dump that calculation on creating on updating.
 
What do you mean by calculate the up votes and down votes at the same time?


Regards,
Chetan Ganji
+91-900-483-4183


DJANGO DEVELOPER

unread,
Jun 25, 2021, 8:27:48 AM6/25/21
to django...@googlegroups.com
Chetan I got what you're saying. so how diff_votes will be updated? do have I to apply the same logic as Oba discussed above?
and yes by calculating the up and down votes at the same time was that, if a user up votes my post and another user down votes my post then should be ranked accordingly.
means I just want to rank my post higher if there are more up votes than down votes. I think I have described well, what I want to apply at the moment.

Ryan Nowakowski

unread,
Jun 25, 2021, 12:00:32 PM6/25/21
to Django users
On Thu, Jun 24, 2021 at 07:15:09AM -0700, DJANGO DEVELOPER wrote:
> Hi Django experts.
> I am building a Django, DRF based mobile app and I want to have
> functionality of up votes and down votes for posts that user will post.
> So what I want to say here that, if an user upvotes a post then it should
> be get higher ranks as quora questions do. and if there are more down votes
> than up votes then a post should be moved down ward rather than going up.
> I have applied a logic already here and shared the screenshots as well. but
> I am sure that there is a better logic or solution for this problem.

Do you want your users to be able to change or delete their vote?
In that case, you'll need to keep track of who voted what. Maybe create
a model like this:

class VoteQuerySet(models.QuerySet):

def down(self):
"""Return only the down votes"""
return self.filter(value__lt=0)

def up(self):
"""Return only the up votes"""
return self.filter(value__gt=0)

def down_total(self):
"""Return the down vote total as a negative number"""
return self.down().aggregate(Sum('value'))['value__sum']

def up_total(self):
"""Return the up vote total as a positive number"""
return self.up().aggregate(Sum('value'))['value__sum']

def total(self):
"""Return the total of all up and down votes"""
return self.aggregate(Sum('value'))['value__sum']


class Vote(models.Model):
"""A user's up or down vote for a post

"value" should be -1 for a down vote and 1 for an up vote

"""
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
value = models.SmallIntegerField()

objects = VoteQuerySet.as_manager()

class Meta:
unique_together = (user, post)

def vote_up(self):
self.value = 1

def vote_down(self):
self.value = -1


You can then vote like this:

vote = Vote(user=user, post=post)
vote.vote_up() # or vote.vote_down()
vote.save()


Here's a post's up vote count:

post.vote_set.up_total()


You can change a user's vote like this:

vote = user.vote_set.get(post=post)
vote.vote_down()

... or delete:

vote.delete()


Any finally, here's how you can sort your posts:

Post.objects.all().annotate(vote_total=Sum('vote__value')).order_by('-vote_total')


Caveat: code untested



Hope this helps!

Ryan

DJANGO DEVELOPER

unread,
Jun 25, 2021, 2:39:02 PM6/25/21
to Django users
Ryan Thank you so much. I will give it try. and let you know about the results

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.

Mike Dewhirst

unread,
Jun 25, 2021, 9:55:10 PM6/25/21
to django...@googlegroups.com
HE lmbo pop l9m6oo9k



--
(Unsigned mail from my phone)

DJANGO DEVELOPER

unread,
Jun 26, 2021, 12:36:01 AM6/26/21
to Django users
Hi Mr Mike.
Can you please share you knowledge here to help me?

Reply all
Reply to author
Forward
0 new messages