themanatuf
themanatuf

Reputation: 3130

Django count specific items of a many-to-one relationship

I have a Django app where users post messages and other users can vote the answers up or down, very similar to SO. I'm having an issue trying to get the "thumbs up" and "thumbs down" counts from within the template and I'm hoping someone can help me. The PostVote is a many-to-one relationship with the Post class. Here is what my model looks like:

class Post(models.Model):
    account = models.ForeignKey(Account)
    message = models.CharField(max_length=1024)
    timestamp = models.DateTimeField('post timestamp')

class PostVote(models.Model):
    post = models.ForeignKey(Post)
    account = models.ForeignKey(Account)
    vote = models.CharField(max_length=16, choices=VOTE_CHOICES)
    timestamp = models.DateTimeField('vote timestamp')

Here is how I'm getting my posts:

posts = Post.objects.all().order_by('-timestamp')[:10]

My template looks roughly like:

{% for post in posts %}
<div>Thumbs up count: {{ WHAT_HERE }}</div>
<div>Thumbs down count: {{ WHAT_HERE }}</div>
{% endfor %}

How can I get the counts in there? I'm sure it involves 'annotate' somehow, but I'm having a difficult time coming up with this one. Any help would be greatly appreciated!

Upvotes: 1

Views: 3042

Answers (1)

Matt Williamson
Matt Williamson

Reputation: 40193

You shouldn't really be doing logic in your templates. Add a couple count methods to your Post model:

class Post(models.Model):
    account = models.ForeignKey(Account)
    message = models.CharField(max_length=1024)
    timestamp = models.DateTimeField('post timestamp')

    def upvote_count(self):
        return self.postvote_set.filter(vote=VOTE_CHOICES[0][0]).count()

    def downvote_count(self):
        return self.postvote_set.filter(vote=VOTE_CHOICES[1][0]).count()

Then use them in your template:

{% for post in posts %}
<div>Thumbs up count: {{ post.upvote_count }}</div>
<div>Thumbs down count: {{ post.downvote_count }}</div>
{% endfor %}

Upvotes: 2

Related Questions