I have a Django app where I want to display a page containing user posts which can be liked by other users by clicking on a Font Awesome Icon which futher is in an anchor tag. When a post is liked by a user, the icon class should be changed from fa-heart
to fa-heart-o
and vice-versa. To achieve this an Ajax request is made by the click event on the icon. This changes the icon and increments/decrements the like count.
I have this like FBV:
#feeds/views.py
@login_required
def like(request):
post_id = request.GET.get("post_id", "")
user = request.user
post = Post.objects.get(pk=post_id)
liked= False
like = Like.objects.filter(user=user, post=post)
if like:
like.delete()
else:
liked = True
Like.objects.create(user=user, post=post)
resp = {
'liked':liked
}
response = json.dumps(resp)
return HttpResponse(response, content_type = "application/json")
And in urls.py
:
urlpatterns=[
path('like/', views.like, name='like'),
]
This is the template
{% for post in posts %}
......
</li>
<li>
{% if post in liked_post %}
<span class="like" data-toggle="tooltip" title="Unlike">
<a href="{% url 'like' %}" id="like" post_id="{{ post.id }}"><i class="fa fa-heart"></i></a>
<ins>{{ post.likes.count }}</ins>
</span>
</a>
{% else %}
<span class="like" data-toggle="tooltip" title="Like">
<a href="{% url 'like' %}" id="like" post_id="{{ post.id }}"><i class="fa fa-heart-o"></i></a>
<ins>{{ post.likes.count }}</ins>
</span>
</a>
{% endif %}
</li>
...
{% endfor %}
This is the Ajax Call.
$('#like').click(function (e) {
console.log('requested !')
var _this = $(this);
e.preventDefault();
$.ajax({
type: "GET",
url: "{% url 'like' %}",
data:{
post_id: _this.attr('post_id')
}
success: function (res) {
if (res.liked){
icon = _this.find("i");
icon.toggleClass("fa-heart fa-heart-o");
console.log('liked');
}
else{
icon = _this.find("i");
icon.toggleClass("fa-heart-o fa-heart");
console.log('unliked');
}
}
});
});
Now the problem is : whenever I click the heart icon, the page gets redirected to /like
(which I presume to not occur since there is a use of preventDefault();
) and I cannot like the post.
How could I solve that ? I have tried different solutions like these:
How to change icon using ajax call
Change anchor text and icon with jquery
How can I change an element's class with JavaScript?
Change the color of the icon in jquery (django project)
But none of these worked for me. So the question is how could I implement this ? Also, how can I change the likes count after a successful ajax call ?