Display the number of comments of each post related to the same post in django

Question:

Hello friends I am building a blog and I have encountered a problem. My problem is that when I want to display the number of comments for each post, on the main page of the blog number of comments displays all posts that have comments, but the number of comments for each post is the same. In the event that post 2 has 3 comments and the other has 1 comment.

You can see in this picture.
Image

This is Post model

class Post(models.Model):
STATUS_CHOICES = (
    ('draft', 'Draft'),
    ('published', 'Published'),
)
title = models.CharField(max_length=255, unique=True)
slug = models.SlugField(max_length=255, unique=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
body = models.TextField()
created_date = models.DateTimeField(auto_now_add=True)
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
image = models.ImageField(null=True, blank=True, upload_to="images/")

def __str__(self):
    return self.title

def get_absolute_url(self):
    return reverse('post_detail', args=[self.created_date.year,
                                        self.created_date.strftime('%m'),
                                        self.created_date.strftime('%d'),
                                        self.slug])

def active_comment(self):
    return self.comments.filter(active=True)

This is Comment model

class Comment(models.Model):
post = models.ForeignKey(Post, related_name="comments", on_delete=models.CASCADE)
name = models.CharField(max_length=100)
email = models.EmailField()
comment = models.CharField(max_length=500)
active = models.BooleanField(default=False)
created_date = models.DateTimeField(auto_now_add=True)

def __str__(self):
    return "{} by {}".format(self.comment, self.name)

This is my views.py

def post_list(request):
posts = models.Post.objects.filter(status='published')
paginator = Paginator(posts, 4)
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
comment_count = models.Comment.objects.filter(active=True).count()
context = {
    'page_obj': page_obj,
    'comment_count': comment_count,
}
# print(posts)
return render(request, "post_list.html", context=context)

And this too post_list.html

        <article class="col-12 col-md-6 tm-post">
        <hr class="tm-hr-primary">

        <a href="{{ post.get_absolute_url }}"
           class="effect-lily tm-post-link tm-pt-60">
            <div class="tm-post-link-inner">
                <img src="/{{ post.image }}/" alt="Image" class="img-fluid">
            </div>

            <h2 class="tm-pt-30 tm-color-primary tm-post-title">{{ post.title }}</h2>
        </a>

        <p class="tm-pt-30">
            {{ post.body|slice:254 }}
        </p>

        <div class="d-flex justify-content-between tm-pt-45">
            <span class="tm-color-primary">Travel . Events</span>
            <span class="tm-color-primary">{{ post.created_date.year }}/{{ post.created_date.month }}/{{ post.created_date.day }}</span>
        </div>

        <hr>

        <div class="d-flex justify-content-between">
                <span>
                    {% for comment in post.active_comment|slice:"1" %}
                        {{ comment_count }}<span> Comment</span>
                    {% endfor %}
                </span>
            <span>{{ post.author|capfirst }}</span>
        </div>
    </article>

please guide me.

Asked By: Hamed 3dart

||

Answers:

You can .annotate(…) [Django-doc] with:

from django.db.models import Count, Q

# …

posts = Post.objects.annotate(number_of_comments=Count('comment', filter=Q(comment__active=True)))

The Post objects that arise from this QuerySet will have an extra attribute .number_of_comments.

Answered By: Willem Van Onsem

based on @willem post you need to edit your template accordingly too:

posts = Post.objects.annotate(number_of_comments=Count('comment', filter=Q(comment_set__active=True)))

and in the template

<div class="d-flex justify-content-between">
   <span>{{post.number_of_comments}}</span>
   <span>{{ post.author|capfirst }}</span>
</div>
Answered By: Trafalino

You specified the related_name to be “comments” inside the comment model.
That is where the Fielderror is coming from
Change the “comment_set” inside the query to “comments” and let’s see

Answered By: Prince Asante
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.