Reputation: 65
I have a view which displays all my posts. Post has ForeignKey
relation with comment
.I want to be able to display the total number of comments
related to each post in a Listview
. Like on facebook feedback one can see the total number of comments
on each post display on user activity feed .
Model. py
class Post(models.Model):
name=models.CharField(max_length=230,null=True)
text=models.TextArea(null=True)
class Comments(models.Model):
comment=models.TextArea(null=True)
post=models.ForeignKey(Post,related_name="post",null=True,on_delete=model.CASCADE)
View.py
def PostListView(request):
#getting all post objects
allpost=Post.objects.all()
#getting all comments
allcomments=Comments.objects.all()
template_name="post.html"
context={'allpost':allpost,'allcomments':allcomments}
return render(request,template_name,context)
def PostDetail(request,slug):
postinstance=get_object_or_404(Post,slug)
#getting comments for this post
comments_for_post=Comments.objects.all().filter(post=postinstance)
#get the total count for comments for post
commentcount=comments_for_post.count()
In Listview
I want to be able to display the total number of comments
related for each post
. In Listview
template I want something like this:
{% for post in allpost %}
{{post.name}}
#get total number of comments for each post
{{commentcount}}
{% endfor %}
Note I have no problem displaying the total number of comments for a post in DetailView . Please i need help in handling this query
Upvotes: 0
Views: 559
Reputation: 958
You don't have to write any queryset. This can be achieved in your template:
# for big numbers
{% load humanize %}
{% for post in allpost %}
{{post.name}}
#get total number of comments for each post
{{post.post.count|intword}}
{% endfor %}
=======
Optional but recommended: Change the related_name in your Comment model as such:
class Comments(models.Model):
comment=models.TextArea(null=True)
post=models.ForeignKey(Post,related_name="comments",null=True,on_delete=model.CASCADE)
Then in the template:
# for big numbers
{% load humanize %}
{% for post in allpost %}
{{post.name}}
#get total number of comments for each post
{{post.comments.count|intword}}
{% endfor %}
Edit: For formating big numbers, add 'django.contrib.humanize' to your INSTALLED_APPS.
Upvotes: 0
Reputation: 482
What you need is "group by" SQL equivalent.
from django.db.models import Count
Post.objects.values('post').annotate(dcount=Count('post'))
By the way, in your Comment class, the convention is to code :
post=models.ForeignKey(Post,related_name="comments",null=True,on_delete=model.CASCADE)
instead of :
post=models.ForeignKey(Post,related_name="post",null=True,on_delete=model.CASCADE)
Upvotes: 0
Reputation: 599580
You should use an annotation on your Post query.
from django.db.models import Count
allpost = Post.objects.all().annotate(commentcount=Count('post'))
Now you can do {{ post.commentcount }}
in your template.
Note, the related_name
on your FK to Post makes no sense, the related_name
points from Post to Comments so should be called comments
. Even better, leave it as the default, which would be comment_set
.
Upvotes: 0