I'm fighting with this problem during several days and can not find the solution for my case. I'm trying to make system of likes without refreshing the page. In synchronous mode system of likes and dislikes works fine, but when I'm trying to add AJAX, I'm getting 405 and only one last comment is working for one click, I understand problem that Ajax doesn't understand django urls with id or pk like my variant {% url 'store:like' comment.pk %} , but how it can be solved?
There is this part from the template:
{% for comment in comments %}
<h6 class="card-header">
{{ comment.author }}<small> добавлен {{ comment.created_at|date:'M d, Y H:i' }} </small>
</h6>
<div class="card-body">
<h4>{{ comment }}</h4>
<form id="like-{{comment.pk}}" method="POST" action="{% url 'store:add_like' comment.pk %}">
{% csrf_token %}
<button style="background-color: transparent; border: none; box-shadow: none;" type="submit">
<a class="btn btn-success" id="like-count-{{comment.pk}}"> Likes {{ comment.likes.all.count }}</a>
</button>
</form>
</div>
{% empty %}
<p>Для данного товара ещё нет комментариев.</p>
{% endfor %}
my ajax call in the same template:
<script type="text/javascript">
$(document).ready(function(){
$('[id^="like-"]').submit(function(e){
e.preventDefault();
var endpoint = $(this).attr('action');
var serializedData = $(this).serializeArray();
$.ajax({
type: 'POST',
url: endpoint,
data: serializedData,
success: function(response) {
$( "#like-count-"+response["id"].toString()).text("Likes "+response["like_count"]);
},
error: function(rs, e) {
alert(rs.responseText);
}
});
})
This part from urls:
path('products/<int:pk>/like/', addlike, name='like'),
View for like:
@api_view(['POST'])
def addlike(request, pk, *args, **kwargs):
is_ajax = request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
if request.method == 'POST' and is_ajax:
post = Comment.objects.get(pk=pk)
is_dislike = False
for dislike in post.dislikes.all():
if dislike == request.user:
is_dislike = True
break
if is_dislike:
post.dislikes.remove(request.user)
is_like = False
for like in post.likes.all():
if like == request.user:
is_like = True
break
if not is_like:
post.likes.add(request.user)
if is_like:
post.likes.remove(request.user)
all_post_likes = post.total_likes() (function from models)
return JsonResponse({"success": True, "like_count": all_post_likes, "id": pk}, status=200)
else:
return JsonResponse({"success": False}, status=400)
How to force AJAX to call in pk what I need? (Finally I found the solution, updated the final version of the code)