WannaInternet
WannaInternet

Reputation: 424

Django - How to sort Post model by votes?

I'm trying to sort posts in views.py with the greatest number of votes at the very top to the least at the bottom.

Here's what I have so far:

Post model in models.py

class Post(models.Model):
    title = models.CharField("HeadLine", max_length=256, unique=True)
    creator = models.ForeignKey(User, on_delete= models.SET_NULL, null=True)
    created_on = models.DateTimeField(auto_now_add=True)
    url = models.URLField("URL", max_length=256,blank=True)
    description = models.TextField("Description", blank=True)
    votes = models.IntegerField(null=True)
    comments = models.IntegerField(null=True)

    def __unicode__(self):
        return self.title
    
    def count_votes(self):
        self.votes = Vote.objects.filter(post = self).count()

    @property
    def sort_by_votes(self):
        return Vote.objects.filter(post = self).count()

    def count_comments(self):
        self.comments = Comment.objects.filter(post = self).count()

list of posts in views.py

 def NewPostListView(request):

    posts = sorted(Post.objects.all(), key=lambda p: p.sort_by_votes, reverse = True)
    for post in posts:
        post.count_votes()
        print(post)
        post.count_comments()
    context = {
        'posts': posts,
    }
    return render(request,'postlist.html', context)

I'm trying to do the equivalent of posts = Post.objects.all().order_by('count_votes'), but I get a "Cannot resolve keyword" error. So far, using the sorted() seems to work, but sometimes the upvote value isn't correct. How can I get a QuerySet to sort posts by votes?

Upvotes: 0

Views: 407

Answers (3)

jsonderulo
jsonderulo

Reputation: 1494

If you want to set votes as your default ordering for the Post model you can set the ordering attribute under Post class Meta

class Post(models.Model):
    ...

    class Meta:
        ordering = "-votes"

Note the negative as you want to sort in descending order (greatest value on top)

Upvotes: 0

Mattia
Mattia

Reputation: 1129

Since your function count_votes is callig a model named Votes i think that in your Post model you have a foreign key to the Votes model or vice versa. If not i suggest to make it.

Assuming this, you can use annotate

from django.db.models import Count
votes = Post.objects.annotate(count_votes=Count('votes')).order_by('count_votes')

Upvotes: 2

Anh Tran
Anh Tran

Reputation: 105

Have you tried posts = Post.objects.all().order_by('votes')?

count_votes is the method of Post, not an attribute. However, votes is.

Upvotes: 0

Related Questions