I’ve got two models:
class Post(models.Model):
#some fields
pass
class Vote(models.Model):
post = mdoels.ForeignKey(Post)
value = models.IntegerField()
Votes’ value can be either 1 or -1 (user can vote up or down).
How can i get a list of posts, ordered by their rating?
You have to use annotation. https://docs.djangoproject.com/en/dev/topics/db/aggregation/
Then you need to import
Sumand can get a list of posts ordered by theirvote_totallike:EDIT:
Here’s an example. Create several post objects and Vote Objects
Then
posts = Post.objects.annotate(vote_total=Sum('vote__value')).order_by('-vote_total')will lead to[(post.name, post.vote_total) for post in posts]being.This has an issue as things with no posts go at the very end. As django’s
Sumaggregation function takes the sum of no entries as None, not 0. This could be solved if you initially gave every post a vote with value 0 (or value 1 like reddit’s system), you wouldn’t get the None: e.g.:Then you’ll get
EDIT: Added type to the Vote model (done above), per comment about different vote types.
You should be able to do something like (replace ‘yourappname’ with the name of your application to get the right db table):
Now each post now will have a
vote_total, as wellawesome_totalanduseful_totalin one query to the database. A bit uglier than the ORM, but still quite readable (and this is how the Sum aggregation works. ). You still will have to give each category of votes an initial vote to get past the None appearing out of order.