I want to get a variable on the views.py file that retrieves the list of likes for each post. So, then on the HTML file, I would use .count
so I can get the number of items on the list and finally be displayed on the DOM.
I first made classes on models.py
. There, I have 3 classes: User, Post, and Like. User is from the default User class from Django. Post is a class that gets information about the post like the author, description, and timestamp. And on the Like class, I get the user and post.
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
pass
class Post(models.Model):
author = models.ForeignKey("User", on_delete=models.CASCADE, related_name="user")
description = models.CharField(max_length=1000)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.id}: {self.author}"
class Like (models.Model):
user = models.ForeignKey("User", on_delete=models.CASCADE, default='', related_name="user_like")
post = models.ForeignKey("Post", on_delete=models.CASCADE, default='', related_name="post_like")
def __str__(self):
return f"{self.id}:{self.user} likes {self.post}"
Second, I made a function on views.py
called "index". There, I get the whole list of posts (on the posts
variable), then I tried to create the variable (totalLikesSinglePost
), which should get the list of likes for each post.
def index(request):
posts = Post.objects.all().order_by("id").reverse()
# Pagination Feature (OMIT THIS, IF YOU WANT)
p = Paginator(posts, 10)
pageNumber = request.GET.get('page')
postsPage = p.get_page(pageNumber)
# Total likes of each post. DOESN'T WORK ⏬
for postSingle in posts:
totalLikesSinglePost = Like.objects.all().filter(post = postSingle)
return render(request, "network/index.html", {
"posts": posts,
"postsPage": postsPage,
"totalLikesPost": totalLikesSinglePost
})
Finally, on the HTML file, there I get each post with its information and the number of likes. However, the output just displays the number 0
{% for post in postsPage %}
<div >
<div >
<div id="post-grid">
<div >
<h5>{{ post.author }}</h5>
<div> | {{ post.timestamp }}</div>
<p>{{ post.description }}</p>
<div >
<strong style="color: red">{{ totalLikesPost.count }}</strong> <!--0 IS DISPLAYED-->
</div>
</div>
</div>
</div>
</div>
{% endfor %}
And of course, after that, I created a superuser and went to admin to add some examples to the database. However, I added some new rows on the Like table but does not display the total of likes for each post.
CodePudding user response:
Your totalLikesSinglePost is just a list of Like records of the last post. Try this on your html file:
<strong style="color: red">{{ post.post_like.count }}</strong>
CodePudding user response:
Because totalLikesSinglePost
get override in each round of for loop. It is the total number of likes of the last post.
You need to assign this number to the post as an attribute, like
for post in posts:
post.num_likes = Like.objects.all().filter(post=post).count()
And then in your template
{% for post in posts %}
{# ... #}
{{ post.num_likes }}
{% endfor %}
However, I strongly recommend you using .annotate
from django.db.models import Count
posts = Post.objects.all().order_by('-id')\
.annotate(num_likes=Count('like'))
This will access database only once and save you a lot of time.