I am trying to create a like/unlike button. I am sending a form using fetch to my /like url in python. To test the code I decided to simply return a JSONResponse . It is working but it seems that the page is being reloaded and thus the original state is being returned. That is: original state is 'Unlike', click makes it 'Like' for a small amount of time and then 'Unlike' comes back
Here is my html
{% if request.user not in post.like.all %}
<a href="" class="card-link liked" data-id="{{post.id}}" data-is_liked="false" id="post-like-{{post.id}}">
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-heart" fill="currentColor"
xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M8 2.748l-.717-.737C5.6.281 2.514.878 1.4 3.053c-.523 1.023-.641 2.5.314 4.385.92 1.815 2.834 3.989 6.286 6.357 3.452-2.368 5.365-4.542 6.286-6.357.955-1.886.838-3.362.314-4.385C13.486.878 10.4.28 8.717 2.01L8 2.748zM8 15C-7.333 4.868 3.279-3.04 7.824 1.143c.06.055.119.112.176.171a3.12 3.12 0 0 1 .176-.17C12.72-3.042 23.333 4.867 8 15z" />
</svg>
</a>
{% else %}
<a href="" class="card-link liked" data-id="{{post.id}}" data-is_liked="true" id="post-like-{{post.id}}">
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-heart-fill" fill="currentColor"
xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z" />
</svg>
</a>
{% endif %}
here is my js script
//this is the script for like edit and delete
var like = document.querySelectorAll(".liked")
like.forEach(element => {
handleLike(element);
});
function handleLike(element) {
element.addEventListener('click', () => {
post_id = element.getAttribute('data-id');
is_liked = element.getAttribute('data-is_liked');
icon = document.getElementById(`post-like-${post_id}`);
count = document.getElementById(`post-count-${post_id}`);
console.log(post_id, is_liked);
form = new FormData();
form.append("post_id", post_id);
form.append("is_liked", is_liked);
fetch('/like', {
method: 'POST',
body: form,
}).then((res) => res.json())
.then((res) => {
if (res.status == 201)
if (res.is_liked === 'true') {
{
icon.innerHTML = `<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi - heart - fill" fill="currentColor"
xmlns = "http://www.w3.org/2000/svg" >
<path fill-rule="evenodd"
d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z" />
</svg > `; icon.setAttribute('data-is_liked', 'true')
}
}
});
});
}
here is my python view
def like(request):
if request.method == 'POST':
post_id = request.POST.get('post_id')
is_liked = request.POST.get('is_liked')
return JsonResponse({'is_liked': 'true', 'status': 201}, status=201)
I am new to JS so please help.
The page reloads because you are clicking an <a href=""
which points back to the same page. That is the default behaviour of the browser. You should add href="javascript:void(0)"
For persistence, the comment specifies like is a m2m relation to User. The view should look like this:
post_id = request.POST.get('post_id')
post = Post.objects.get(id=post_id)
is_liked = request.POST.get('is_liked')
if is_liked:
post.like.add(request.user)
else:
post.like.remove(request.user)
I recommend renaming like
to likes