a7me3D
a7me3D

Reputation: 49

Django Like function with ajax

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

Answers (1)

a7me3D
a7me3D

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

Related Questions