Reputation: 49
First of all : I already checked all the related answers and questions .... they didn't help me
so I am trying to create ajax based like button with multiple users and multiple objects or posts i tried a lot but none of them works but i steel have the base
models.py:
class BlogPost(models.Model):
#some fields
class Like (models.Model):
user = models.ForeignKey(User)
post = models.ForeignKey(BlogPost)
views.py
from .models import Like
def PostLikeToggle(request):
#here i want to capture the request check if the user liked the post or
# no by sending user.username and post.title to the endpoint like.html
#and then update his status
return render(request, 'like.html')
urls.py
from plateform import views as plateform
urlpatterns = [
#other urls
url(r'^like/', plateform.PostLikeToggle, name='PostLikeToggle'),]
like.html
{% if liked == 'false' %}
false
{% elif liked == 'true' %}
true
{% endif %}
blogpost.html
#ajax
$('.thumb').click(function () {
$.ajax({
type: 'POST',
url: '/like/',
data: {
'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val(),
},
success: LikePost,
dataType: 'html'
});
function LikePost(data, jqXHR) {
console.log(data)
}
});
UPDATE I tried to figure it out so I added some things
models:
class BlogPost(models.Model):
#some fields
liked = models.ManyToManyField(User, related_name='PostLikeToggle')
#REMOVED class Like (models.Model)
views:
def PostLikeToggle(request):
user = request.user
if request.method == 'POST':
post_id = request.POST['post_id']
post = get_object_or_404(posts, id=post_id)
_liked = user in post.liked.all()
if _liked :
post.liked.remove(user)
else:
post.liked.add(user)
return JsonResponse({'liked':_liked})
So am I on the right way ??
Upvotes: 1
Views: 1674
Reputation: 49
okey I will just post my answer .... it was easy trick but i was little bit stingy ...
In the models file i added ManytoMany field with the relation of users ( many users + many posts)
class BlogPost(models.Model):
#more fields
liked = models.ManyToManyField(User, related_name='PostLikeToggle')
in the views i created the view which it will accept the request from the blogpost views and check if user already liked the post or no ( add the user to the liked field if liked return true remove it if .... )
def PostLikeToggle(request):
user = request.user
if request.method == 'POST':
post_id = request.POST['post_id']
post = get_object_or_404(posts, id=post_id)
_liked = user in post.liked.all()
if _liked :
post.liked.remove(user)
else:
post.liked.add(user)
return JsonResponse({'liked':_liked})
this views is associated with url where we will get the response :
url(r'^like/', plateform.PostLikeToggle, name='PostLikeToggle')
and in your blog post template you will need to link Jquery and add this Ajax function (don't forget to customize it with your own variable class , url ... )
$('.thumb').click(function () {
$.ajax({
type: 'POST',
url: {% url 'PostLikeToggle' %},
data: {
'post_id': {{ post_slug.id }},
'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val(),
},
success: LikePost,
dataType: 'html'
});
function LikePost(data, jqXHR) {
var data = $.parseJSON(data)
if (data['liked']) {
$('.thumb').removeClass("fas fa-thumbs-up").addClass('far fa-thumbs-up')
}
else
{
$('.thumb').removeClass("far fa-thumbs-up").addClass('fas fa-thumbs-up')
}
}
});
this worked for this time if there is any exception or you have better way just post it and i will mark it
NOTICE : you have to check if the user if authenticated in the template to hide the like button or redirect him to login ....
Upvotes: 2