skip to Main Content

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.

3

Answers


  1. 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.

    Login or Signup to reply.
  2. 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>
    
    Login or Signup to reply.
  3. 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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search