class Post(models.Model):
designer = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
likes = models.ManyToManyField(User, through="Like", related_name='liked')
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("score:post-detail", kwargs={'pk': self.pk})
class Like(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
value = models.CharField(choices=LIKE_CHOICES,
default='Like', max_length=10)
def toggle_value(self):
if self.value == "Like":
self.value = "Unlike"
else:
self.value = "Like"
def __str__(self):
return str(self.post.pk)
the view:
def like_post(request):
user = request.user
if request.method == 'Post':
post_id = request.POST.get('post_id')
post_obj = Post.objects.get(id=post_id)
like, created = Like.objects.get_or_create(user=user, post_id=post_id)
if not created:
like.toggle_value()
like.save()
return redirect('score:score')
class PostListView(ListView):
model = Post
template_name = "score.html"
ordering = ['-date_posted']
context_object_name = 'posts'
queryset = Post.objects.filter(admin_approved=True)
paginate_by = 5
def get_queryset(self, **kwargs):
queryset = super(PostListView, self).get_queryset(**kwargs):
return queryset.annotate(
total_liked=Count(
'likes',
filter=Q(likes__value="Like")
).annotate(
user_liked=Case(
When(Q(likes__user=self.request.user) & Q(likes__value="Like"), then=Value(True)),
default=Value(False),
output_field = BooleanField()
)
)
Here is the template
{% for post in posts %}
<div style="padding-top:200 px"><strong>{{post.title}}</strong></div>
<form action="{% url 'score:like_post'%}" method='POST' class="ui form">
{% csrf_token %}
<input type='hidden' name='post_id' value="{{post.id}}">
{% if post.user_liked %}
<button class= "ui button positive" type='submit'> Like </button>
{% else %}
<button class= "ui button negative" type='submit'> Unlike </button>
{% endif %}
</form>
<strong>{{post.total_liked}} Likes </strong>
{% endfor %}
Here is the URL
path('', PostListView.as_view(), name='score'),
path('like/', like_post, name='like_post'),
Thank you